UNPKG

4.46 kBPlain TextView Raw
1import { IEnumerable } from "../interface/IEnumerable";
2import IEnumerator from "../interface/IEnumerator";
3import { LinkList } from "../linklist/LinkList";
4import { LinkNode } from "../linklist/LinkNode";
5
6export class CycleLinkList<T> implements IEnumerable<T>{
7 private linklist: LinkList<T>;
8 constructor(){
9 this.linklist = new LinkList<T>();
10 }
11
12 /**
13 * 将链表首尾相连
14 */
15 private setCircle(){
16 this.getTailNode().setNext(this.getHeadNode());
17 }
18
19 /**
20 * 获取单向循环链表的长度
21 */
22 public get Size(){
23 return this.linklist.Size;
24 }
25
26 /**
27 * 向链表中追加一个节点
28 * @param value 要追加的节点值
29 * @returns LinkNode
30 */
31 public append(value: T): LinkNode<T>{
32 const result = this.linklist.append(value);
33 this.setCircle();
34 return result;
35 }
36
37 /**
38 * 向头部插入一个节点
39 * @param value 要插入的节点值
40 * @returns LinkNode
41 */
42 public prepend(value: T): LinkNode<T>{
43 const result = this.linklist.prepend(value);
44 this.setCircle();
45 return result;
46 }
47
48 /**
49 * 根据条件删除节点
50 * @param arg 如果arg是function,则调用arg,将当前节点value传入,否则将arg与当前节点value对比
51 * @returns boolean
52 */
53 public deleteNode(arg: ((item: T) => boolean)|T): boolean{
54 const isFirstOrLast =
55 this.linklist.findNode(arg) === this.getHeadNode()
56 || this.linklist.findNode(arg) === this.getTailNode(),
57 result = this.linklist.deleteNode(arg);
58 // 如果删除头节点或尾节点
59 if (isFirstOrLast){
60 this.setCircle();
61 }
62 return result;
63 }
64
65 /**
66 * 根据条件查找节点
67 * @param arg 如果argfunction,则调用arg,将当前节点value传入,否则将arg与当前节点value对比
68 * @returns LinkNode
69 */
70 public findNode(arg: ((item: T) => boolean)|T): LinkNode<T>{
71 return this.linklist.findNode(arg);
72 }
73
74 /**
75 * 获取头结点
76 * @returns LinkNode
77 */
78 public getHeadNode(): LinkNode<T>{
79 return this.linklist.getHeadNode();
80 }
81
82 /**
83 * 获取尾节点
84 * @returns LinkNode
85 */
86 public getTailNode(): LinkNode<T>{
87 return this.linklist.getTailNode();
88 }
89
90 /**
91 * 推出头节点
92 * @returns LinkNode
93 */
94 public shift(): LinkNode<T>{
95 const result = this.linklist.shift();
96 // 节点数大于0时设置头尾循环
97 if (this.Size){
98 this.setCircle();
99 }
100 return result;
101 }
102
103 /**
104 * 推出尾节点
105 * @returns LinkNode
106 */
107 public pop(): LinkNode<T>{
108 const result = this.linklist.pop();
109 // 节点数大于0时设置头尾循环
110 if (this.Size){
111 this.setCircle();
112 }
113 return result;
114 }
115
116 /**
117 * 在某个节点后面插入一个节点
118 * @param value 要插入的节点值
119 * @param oriNode 在该节点后插入新节点
120 * @returns boolean
121 */
122
123 public insertAfter(value: T, oriNode: LinkNode<T>): boolean{
124 return this.linklist.insertAfter(value, oriNode);
125 }
126
127 /**
128 * 清空链表
129 */
130 public clear(){
131 this.linklist.clear();
132 }
133
134 /**
135 * @returns string
136 */
137 public toString(){
138 return this.linklist.toString();
139 }
140
141 /**
142 * @param arr 数组转单向循环链表
143 * @returns CycleLinkList
144 */
145 public static fromArray<K>(arr: Array<K>): CycleLinkList<K>{
146 if (!arr){
147 return new CycleLinkList<K>();
148 }
149 const linkList = new CycleLinkList<K>();
150 arr.forEach(item => {
151 linkList.append(item);
152 });
153 return linkList;
154 }
155
156 public toArray(){
157 return this.linklist.toArray();
158 }
159
160 getEnumerator(): IEnumerator<T> {
161 let temp = this.getHeadNode();
162 const enumerator = {
163 next: () => {
164 temp = temp.Next;
165 enumerator.Current = {
166 value: temp.Value,
167 done: false,
168 };
169 return enumerator;
170 },
171 Current: {
172 value: temp.Value,
173 done: false,
174 },
175 };
176 return enumerator;
177 }
178}
179
180export default CycleLinkList;