1 | import { IEnumerable } from "../interface/IEnumerable";
|
2 | import IEnumerator from "../interface/IEnumerator";
|
3 | import { LinkList } from "../linklist/LinkList";
|
4 | import { LinkNode } from "../linklist/LinkNode";
|
5 |
|
6 | export 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 |
|
29 |
|
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 |
|
40 |
|
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 |
|
51 |
|
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 如果arg是function,则调用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 |
|
180 | export default CycleLinkList;
|