UNPKG

6.68 kBPlain TextView Raw
1import {DoubleLinkListNode} from "../doublelinklist/ZKDoubleLinkListNode";
2import { IEnumerable } from "../interface/IEnumerable";
3import { IEnumerator } from "../interface/IEnumerator";
4export class DoubleLinkListCycle<T> implements IEnumerable<T>{
5
6 private headNode: DoubleLinkListNode<T> = null;
7 private tailNode: DoubleLinkListNode<T> = null;
8 private size = 0;
9 constructor() {
10 // super();
11 }
12
13 public get Size(){
14 return this.size;
15 }
16
17 /**
18 * 向链表中追加一个节点
19 * @param node
20 */
21 public append(node: T){
22 const currentNode = new DoubleLinkListNode(node);
23 if (!this.tailNode){
24 this.headNode = this.tailNode = currentNode;
25 this.headNode.setNext(this.tailNode);
26 this.tailNode.setPre(this.headNode);
27 }else{
28 currentNode.setPre(this.tailNode);
29 currentNode.setNext(this.headNode);
30 this.tailNode.setNext(currentNode);
31 this.headNode.setPre(currentNode);
32 this.tailNode = currentNode;
33
34 }
35 this.size++;
36 return this;
37 }
38 /**
39 * 向头部插入一个节点
40 * @param node
41 */
42 public prepend(node: T){
43 const currentNode = new DoubleLinkListNode(node);
44 if (!this.headNode){
45 this.headNode = this.tailNode = currentNode;
46 this.headNode.setNext(this.tailNode);
47 this.tailNode.setPre(this.headNode);
48 }else{
49 this.headNode.setPre(currentNode);
50 currentNode.setNext(this.headNode);
51 currentNode.setPre(this.tailNode);
52 this.tailNode.setNext(currentNode);
53 this.headNode = currentNode;
54 }
55 this.size++;
56 return this;
57 }
58
59 /**
60 * 清空所有节点
61 */
62 private emptyList(){
63 this.headNode = this.tailNode = null;
64 this.size = 0;
65 }
66
67 /**
68 * 推出头节点
69 * @returns DoubleLinkListNode<T>
70 */
71 public shift(): DoubleLinkListNode<T>{
72 const result = this.headNode;
73 if (this.headNode === this.tailNode){
74 this.emptyList();
75 }else{
76 this.headNode = this.headNode.next;
77 this.headNode.setPre(this.tailNode);
78 this.size--;
79 }
80 return result;
81 }
82
83 /**
84 * 推出尾节点
85 * @returns DoubleLinkListNode<T>
86 */
87 public pop(): DoubleLinkListNode<T>{
88 const result = this.tailNode;
89 if (this.headNode === this.tailNode){
90 this.emptyList();
91 }else{
92 this.tailNode = this.tailNode.Prev;
93 this.tailNode.setNext(this.headNode);
94 this.size--;
95 }
96 return result;
97 }
98
99 /**
100 * 根据条件删除节点
101 * @param arg 如果arg是function,则调用arg,将当前节点value传入,否则将arg与当前节点value对比
102 */
103 public deleteNode(arg: any){
104 const deleteArr: Array<number> = [];
105 if (this.isEmpty()){
106 return deleteArr;
107 }
108 let cycleNode: DoubleLinkListNode<T> = this.headNode;
109 let index = 0;
110 while (cycleNode){
111 const match = typeof arg === "function" ? arg(cycleNode.value) : (cycleNode.value === arg);
112 let deleteNode: DoubleLinkListNode<T> = null;
113 if (match){
114 // 如果只有一个节点,清空链表
115 if (this.headNode === this.tailNode){
116 this.emptyList();
117 break;
118 }else{
119 // 设置被删除节点的上一个节点的next指向被删除节点的下一个节点
120 // 被删除节点的下一个节点的prev指向被删除节点的上一个节点
121 cycleNode.Prev.setNext(cycleNode.Next);
122 cycleNode.Next.setPre(cycleNode.Prev);
123 }
124 deleteNode = cycleNode;
125 deleteArr.push(index);
126 }
127 cycleNode = cycleNode.Next;
128 const shouldBreak = cycleNode === this.headNode;
129
130 if (deleteNode){
131 if (deleteNode === this.headNode){
132 this.headNode = deleteNode.Next;
133 }
134 if (deleteNode === this.tailNode){
135 this.tailNode = deleteNode.Prev;
136 }
137 deleteNode.setNext(null);
138 deleteNode.setPre(null);
139 }
140
141 if (shouldBreak){
142 break;
143 }
144 index++;
145 }
146 }
147
148 /**
149 * 根据条件查找节点
150 * @param arg 如果arg是function,则调用arg,将当前节点value传入,否则将arg与当前节点value对比
151 * @returns DoubleLinkListNode
152 */
153 public findNode(arg: any): DoubleLinkListNode<T>{
154 let cycleNode: DoubleLinkListNode<T> = this.headNode;
155 let result: DoubleLinkListNode<T> = null;
156 while (cycleNode){
157 const match = typeof arg === "function" ? arg(cycleNode.value) : (cycleNode.value === arg);
158 if (match){
159 result = cycleNode;
160 break;
161 }else if (cycleNode === this.tailNode){
162 break;
163 }
164 cycleNode = cycleNode.Next;
165 }
166 return result;
167 }
168
169 /**
170 * 获取头结点
171 * @returns DoubleLinkListNode
172 */
173 public getHeadNode(): DoubleLinkListNode<T>{
174 return this.headNode;
175 }
176
177 /**
178 * 获取尾节点
179 * @returns DoubleLinkListNode
180 */
181 public getTailNode(): DoubleLinkListNode<T>{
182 return this.tailNode;
183 }
184
185 /**
186 * 是否为空链表
187 * @returns boolean
188 */
189 public isEmpty(): boolean{
190 return !this.Size;
191 }
192
193 /**
194 * @returns string
195 */
196 public toString(){
197 let temp = this.headNode;
198 const arr: Array<DoubleLinkListNode<T>> = [];
199 while (temp){
200 arr.push(temp);
201 temp = temp.Next;
202 if (temp === this.headNode){
203 break;
204 }
205 }
206 return arr.toString();
207 }
208
209 getEnumerator(): IEnumerator<T> {
210 let temp = this.getHeadNode();
211 const enumerator = {
212 next: () => {
213 temp = temp.Next;
214 enumerator.Current = {
215 value: temp.value,
216 done: false,
217 };
218 return enumerator;
219 },
220 Current: {
221 value: temp.value,
222 done: false,
223 },
224 };
225 return enumerator;
226 }
227}
228
229export default DoubleLinkListCycle;