1 class Program
2 {
3 static void Main(string[] args)
4 {
5 LinkedList<int> list = new LinkedList<int>();
6 for (int i = 0; i < 100; i++)
7 {
8 list.Append(i);
9 }
10 list.PrintAllNode();
11 }
12 }
13 public class Node<T>
14 {
15 public T Data;//当前值
16 public Node<T> Next;//下一个节点
17 public Node(T item)
18 {
19 this.Data = item;
20 }
21 public Node()
22 {
23 // this.val = item;
24 }
25 }
26
27 // 定义一个泛型单链表类
28 public class LinkedList<T> /*: IListDS<T>*/
29 {
30 #region 字段
31 private Node<T> head; // 单链表头结点
32 #endregion
33
34 #region 属性
35 // 头结点
36 public Node<T> Head
37 {
38 get
39 {
40 return head;
41 }
42 set
43 {
44 head = value;
45 }
46 }
47 #endregion
48
49 #region 基本操作
50 // 构造方法
51 public LinkedList()
52 {
53 head = null;
54 }
55
56 // 获取单链表的长度
57 public int GetLength()
58 {
59 // 设置指针指向头结点
60 Node<T> p = head;
61
62 // 定义存储数据的变量
63 int len = 0;
64
65 // 当当前指针指向的地址不是为null时表示存在该结点
66 while (p != null)
67 {
68 len++;
69 p = p.Next; // 指针继续指向引用域所指向的结点
70 }
71
72 return len;
73 }
74
75 // 清空单链表
76 // 此处只是将头结点的引用域设置为null的逻辑清空,在内存中数据依旧存在
77 // 但是.NET的垃圾回收器会为我们回收这部分垃圾
78 public void Clear()
79 {
80 head = null;
81 }
82
83 // 判断单链表是否为空
84 public bool IsEmpty()
85 {
86 // 根据头结点的引用域是否为null判断是否为空
87 if (head == null)
88 {
89 return true;
90 }
91 else
92 {
93 return false;
94 }
95 }
96
97 // 在单链表尾部追加数据元素
98 public bool Append(T item)
99 {
100 Node<T> node = new Node<T>(item);
101 Node<T> p = new Node<T>();
102
103 // 判断此时是否为空表,是则直接修改头结点的引用域
104 if (head == null)
105 {
106 head = node;
107 }
108 // 不是则遍历结点,找到最后最后一个结点
109 else
110 {
111 p = head;
112 while (p.Next != null)
113 {
114 p = p.Next;
115 }
116
117 // 设置最后一个结点的引用域为追加数据元素的地址
118 p.Next = node;
119 }
120
121 return true;
122 }
123
124 // 在单链表的第i个结点的位置前插入一个值为item的结点
125 public bool Insert(T item, int i)
126 {
127 // 判断是否为空表
128 if (IsEmpty())
129 {
130 Console.WriteLine("单链表中不存在数据元素,无法执行插入操作,操作失败!");
131 return false;
132 }
133 // 判断用户指定的插入位置是否合理
134 else if (i < 1)
135 {
136 Console.WriteLine("插入元素的位置不正确,无法执行插入操作,操作失败!");
137 return false;
138 }
139 // 判断是否操作第一个结点
140 else if (i == 1)
141 {
142 // 操作第一个结点
143 Node<T> node = new Node<T>(item);
144 node.Next = head;
145 head = node;
146 return true;
147 }
148 // 执行一般插入操作
149 else
150 {
151 Node<T> p = head;
152 Node<T> pre = new Node<T>();
153 int j = 1;
154
155 // 遍历直到当前结点的位置为i
156 // 如果插入位置超过单链表长度,则插入失败
157 while (p.Next != null && j < i)
158 {
159 pre = p;
160 p = p.Next;
161 j++;
162 }
163
164 if (j == i)
165 {
166 Node<T> node = new Node<T>(item);
167 node.Next = p;
168 pre.Next = node;
169 return true;
170 }
171 else
172 {
173 Console.WriteLine("插入元素的位置不正确,无法执行插入操作,操作失败!");
174 return false;
175 }
176 }
177 }
178
179
180 // 在单链表的第i个结点的位置后插入一个值为item的结点
181 public bool InsertPost(T item, int i)
182 {
183 // 判断是否为空表
184 if (IsEmpty())
185 {
186 Console.WriteLine("单链表中不存在数据元素,无法执行插入操作,操作失败!");
187 return false;
188 }
189 // 判断用户指定的插入位置是否合理
190 else if (i < 1)
191 {
192 Console.WriteLine("插入元素的位置不正确,无法执行插入操作,操作失败!");
193 return false;
194 }
195 // 判断是否操作第一个结点
196 else if (i == 1)
197 {
198 // 操作第一个结点
199 Node<T> node = new Node<T>(item);
200 node.Next = head;
201 head = node;
202 return true;
203 }
204 // 执行一般插入操作
205 else
206 {
207 Node<T> p = head;
208 Node<T> pre = new Node<T>();
209 int j = 1;
210
211 // 遍历直到当前结点的位置为i
212 // 如果插入位置超过单链表长度,则插入失败
213 while (p.Next != null && j < i)
214 {
215 pre = p;
216 p = p.Next;
217 j++;
218 }
219
220 if (j == i)
221 {
222 Node<T> node = new Node<T>(item);
223 node.Next = p.Next;
224 p.Next = node;
225 return true;
226 }
227 else
228 {
229 Console.WriteLine("插入元素的位置不正确,无法执行插入操作,操作失败!");
230 return false;
231 }
232 }
233 }
234
235 // 删除单链表的第i个结点,只是修改引用域,逻辑上的删除,由垃圾回收器回收
236 public T Delete(int i)
237 {
238 // 定义要返回的元素,并赋初值
239 T tmp = default(T);
240
241 // 判断是否为空表
242 if (IsEmpty())
243 {
244 Console.WriteLine("单链表中不存在数据元素,无法执行删除操作,操作失败!");
245 }
246 // 判断用户指定的删除位置是否合理
247 else if (i < 1)
248 {
249 Console.WriteLine("删除元素的位置不正确,无法执行删除操作,操作失败!");
250 }
251 // 判断是否操作第一个结点
252 else if (i == 1)
253 {
254 // 操作第一个结点
255 Node<T> node = head;
256 head = head.Next;
257 tmp = node.Data;
258 }
259 // 执行一般删除操作
260 else
261 {
262 Node<T> node = new Node<T>();
263 Node<T> p = head;
264 int j = 1;
265
266 while (p.Next != null && j < i)
267 {
268 node = p;
269 p = p.Next;
270 j++;
271 }
272
273 if (j == i)
274 {
275 node.Next = p.Next;
276 tmp = p.Data;
277 }
278 else
279 {
280 Console.WriteLine("删除元素的位置不正确,无法执行删除操作,操作失败!");
281 }
282 }
283
284 // 返回被操作的元素(或默认值)
285 return tmp;
286 }
287
288 // 获得单链表中第i个数据元素
289 public T GetElem(int i)
290 {
291 // 定义要返回的元素,并赋初值
292 T tmp = default(T);
293
294 // 判断是否为空表
295 if (IsEmpty())
296 {
297 Console.WriteLine("单链表表中不存在数据元素,无法执行获取操作,操作失败!");
298 }
299 // 判断用户指定的获取位置是否合理
300 else if (i < 1)
301 {
302 Console.WriteLine("获取元素的位置不正确,无法执行获取操作,操作失败!");
303 }
304 // 执行获取操作,如果位置超过单链表长度,则获得到的为最后一个结点的值
305 else
306 {
307 Node<T> p = new Node<T>();
308 p = head;
309 int j = 1;
310
311 while (p.Next != null && j < i)
312 {
313 p = p.Next;
314 j++;
315 }
316
317 tmp = p.Data;
318 }
319
320 // 返回被操作的元素(或默认值)
321 return tmp;
322 }
323
324 // 在单链表中查找值为value的结点
325 public int Locate(T value)
326 {
327 // 定义要返回的索引,-1表示未找到或查找失败【注意:此处i表示是索引,而非位置!】
328 int i;
329
330 // 判断是否为空表
331 if (IsEmpty())
332 {
333 Console.WriteLine("单链表表中不存在数据元素,无法执行查找操作,操作失败!");
334 i = -1;
335 }
336 // 执行查找操作
337 else
338 {
339 Node<T> p = new Node<T>();
340 p = head;
341 i = 0;
342 while (!p.Data.Equals(value) && p.Next != null)
343 {
344 p = p.Next;
345 i++;
346 }
347 }
348
349 // 返回查找到的索引(或默认值)
350 return i;
351 }
352 #endregion
353
354 #region 高级操作
355 // 打印单链表所有结点
356 public void PrintAllNode()
357 {
358 // 判断是否为空表
359 if (IsEmpty())
360 {
361 Console.WriteLine("单链表表中不存在数据元素,无法执行打印操作,操作失败!");
362 }
363 // 执行打印操作
364 else
365 {
366 Console.WriteLine("打印单链表中的数据元素:\n");
367 Node<T> p = new Node<T>();
368 p = head;
369 while (p.Next != null)
370 {
371 Console.Write(p.Data + "\t");
372 p = p.Next;
373 }
374
375 // 打印最后一个结点
376 Console.Write(p.Data + "\t");
377
378 Console.WriteLine();
379 }
380 }
381 #endregion
382 }