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 }