1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4
5 namespace Kingge.Collection
6 {
7 public class LinkList<T> : IList<T>
8 {
9 private class Node<D>
10 {
11 public Node(D data, Node<D> next)
12 {
13 Data = data;
14 Next = next;
15 }
16 public Node(D data)
17 : this(data, null)
18 {
19 }
20 public Node()
21 : this(default(D))
22 {
23 }
24 public D Data { set; get; }
25 public Node<D> Next { set; get; }
26 }
27 private Node<T> _head;
28 private int _count;
29 private Node<T> Head
30 {
31 get { return _head; }
32 set { _head = value; }
33 }
34 public LinkList()
35 {
36 Head = new Node<T>();
37 Count = 0;
38 }
39 public LinkList(IEnumerable<T> nodes)
40 : this()
41 {
42 if (nodes != null)
43 {
44 foreach (T item in nodes)
45 {
46 Add(item);
47 }
48 }
49 }
50 public int IndexOf(T item)
51 {
52 int index = -1;
53 bool flag = false;
54 Node<T> node = Head.Next;
55 while (node != null)
56 {
57 index++;
58 if (node.Data.Equals(item))
59 {
60 flag = true;
61 break;
62 }
63 node = node.Next;
64 }
65 if (flag)
66 {
67 return index;
68 }
69 else
70 {
71 return -1;
72 }
73 }
74
75 public void Insert(int index, T item)
76 {
77 if (IsReadOnly)
78 {
79 throw new InvalidOperationException("IsReadOnly");
80 }
81 else if (index<0)
82 {
83 throw new ArgumentOutOfRangeException("index");
84 }
85 else
86 {
87 int count = 0;
88 bool success = false;
89 Node<T> node = Head;
90 while (node.Next != null)
91 {
92 if (index == count)
93 {
94 Node<T> ItemNode = new Node<T>(item);
95 ItemNode.Next = node.Next;
96 node.Next = ItemNode;
97 Count++;
98 success = true;
99 break;
100 }
101 node = node.Next;
102 count++;
103 }
104 if (!success)
105 {
106 throw new ArgumentOutOfRangeException("index");
107 }
108 }
109 }
110
111 public void RemoveAt(int index)
112 {
113 if (IsReadOnly)
114 {
115 throw new InvalidOperationException("IsReadOnly");
116 }
117 else
118 {
119 int count = 0;
120 bool success = false;
121 Node<T> node = Head;
122 while (node.Next != null)
123 {
124 if (index == count)
125 {
126 node.Next = node.Next.Next;
127 Count--;
128 success = true;
129 break;
130 }
131 node = node.Next;
132 count++;
133 }
134 if (!success)
135 {
136 throw new IndexOutOfRangeException();
137 }
138 }
139 }
140
141 public T this[int index]
142 {
143 get
144 {
145 if (index < 0)
146 {
147 throw new IndexOutOfRangeException();
148 }
149 Node<T> node = Head.Next;
150 int count = 0;
151 while (node != null)
152 {
153 if (index == count)
154 {
155 return node.Data;
156 }
157 node = node.Next;
158 count++;
159 }
160 throw new IndexOutOfRangeException();
161 }
162 set
163 {
164 if (index < 0)
165 {
166 throw new IndexOutOfRangeException();
167 }
168 Node<T> node = Head.Next;
169 bool flag = false;
170 int count = 0;
171 while (node != null)
172 {
173 if (index == count)
174 {
175 node.Data = value;
176 flag = true;
177 break;
178 }
179 node = node.Next;
180 count++;
181 }
182 if (!flag)
183 {
184 throw new IndexOutOfRangeException();
185 }
186 }
187 }
188
189 public void Add(T item)
190 {
191 if (IsReadOnly)
192 {
193 throw new InvalidOperationException("IsReadOnly");
194 }
195 else
196 {
197 Node<T> node = Head;
198 while (node.Next != null)
199 {
200 node = node.Next;
201 }
202 Node<T> last = new Node<T>(item);
203 node.Next = last;
204 Count++;
205 }
206 }
207
208 public void Clear()
209 {
210 if (IsReadOnly)
211 {
212 throw new InvalidOperationException("IsReadOnly");
213 }
214 else
215 {
216 Head.Next = null;
217 Count = 0;
218 }
219 }
220
221 public bool Contains(T item)
222 {
223 Node<T> node = Head.Next;
224 while (node != null)
225 {
226 if (node.Data.Equals(item))
227 {
228 return true;
229 }
230 node = node.Next;
231 }
232 return false;
233 }
234
235 public void CopyTo(T[] array, int arrayIndex)
236 {
237 if (arrayIndex < 0 || arrayIndex > array.Length)
238 {
239 throw new ArgumentOutOfRangeException("arrayIndex");
240 }
241 else
242 {
243 Node<T> node = Head.Next;
244 for (int i = arrayIndex; i < array.Length; i++)
245 {
246 if (node != null)
247 {
248 ICloneable cloneObject = node.Data as ICloneable;
249 if (cloneObject != null)
250 {
251 array[i] = (T)cloneObject.Clone();
252 }
253 else
254 {
255 array[i] = node.Data;
256 }
257 node = node.Next;
258 }
259 else
260 {
261 break;
262 }
263 }
264 }
265 }
266
267 public int Count
268 {
269 get
270 {
271 return _count;
272 }
273 private set
274 {
275 _count = value;
276 }
277 }
278
279 public bool IsReadOnly
280 {
281 set;
282 get;
283 }
284
285 public bool Remove(T item)
286 {
287 Node<T> node = Head;
288 while (node.Next != null)
289 {
290 if (node.Next.Data.Equals(item))
291 {
292 node.Next = node.Next.Next;
293 Count--;
294 return true;
295 }
296 node = node.Next;
297 }
298 return false;
299 }
300
301 public IEnumerator<T> GetEnumerator()
302 {
303 Node<T> node = Head;
304 while (node.Next != null)
305 {
306 node = node.Next;
307 yield return node.Data;
308 }
309 }
310
311 IEnumerator IEnumerable.GetEnumerator()
312 {
313 Node<T> node = Head;
314 while (node.Next != null)
315 {
316 node = node.Next;
317 yield return node.Data;
318 }
319 }
320 }
321 }