using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CSharpLinkedList { class Program { static void Main(string[] args) { var test = new CSharpLinkedList<int>(); var data = Enumerable.Range(1, 50).ToList(); foreach (var i in data) { test.AddLast(i); } Console.WriteLine(test.Count); test.Print(); foreach (var i in data.Where(d => d % 2 == 0)) { test.Remove(i); } Console.WriteLine(test.Count); test.Print(); foreach (var i in data.Where(d => d % 3 == 0)) { test.Remove(i); } Console.WriteLine(test.Count); test.Print(); Console.ReadKey(); } } /// <summary> /// 双向链表 /// </summary> /// <typeparam name="T"></typeparam> public class CSharpLinkedList<T> : IEnumerable<T> { //双向链表的头节点。通过它可以访问到链表所有的节点 //C#选择不把头节点暴露为公共的,这样可以使得用户不能在初始化链表时传入头节点 //防止传入了头节点却忘了设置它的prev和next导致之后插入删除发生错误的问题 //头节点必须通过AddFirst或AddLast方法插入,在那两个方法里,设置头节点的prev和next internal CSharpLinkedListNode<T> head; //C#的链表内部维护一个长度,使得统计长度的时间复杂度为常数 private int count; //对外的 public int Count { get { return count; } } //链表第一个成员 public CSharpLinkedListNode<T> First { get { return head; } } //链表最后一个成员 public CSharpLinkedListNode<T> Last { get { if (head != null) { return head.prev; } return null; } } //构造函数什么都不需要做 public CSharpLinkedList() { } public CSharpLinkedListNode<T> Find(T value) { var next = head; var comparer = EqualityComparer<T>.Default; if (next != null) { //如果传入的不是null,遍历链表 if (value != null) { //泛型不能直接比较,需要引入EqualityComparer while (!comparer.Equals(next.item, value)) { next = next.next; //双向链表转回头意味着遍历结束 if (next == head) { return null; } } return next; } //如果传入的是null,遍历链表,返回第一个值为null的节点 while (next.item != null) { next = next.next; //双向链表转回头意味着遍历结束 if (next == head) { return null; } } return next; } return null; } internal void InsertNodeToEmptyList(CSharpLinkedListNode<T> node) { head = node; head.next = head; head.prev = head; count++; } internal void InsertNodeBefore(CSharpLinkedListNode<T> node, CSharpLinkedListNode<T> newNode) { newNode.next = node; newNode.prev = node.prev; node.prev.next = newNode; node.prev = newNode; count++; } //在链表开头插入节点(插入到head节点之前) public void AddFirst(CSharpLinkedListNode<T> node) { //空链表 if (head == null) { InsertNodeToEmptyList(node); } else { InsertNodeBefore(head, node); } } //在链表开头插入值为value的节点(插入到head节点之前) public void AddFirst(T value) { AddFirst(new CSharpLinkedListNode<T>(value)); } //在链表结尾插入节点 public void AddLast(CSharpLinkedListNode<T> node) { //空链表 if (head == null) { InsertNodeToEmptyList(node); } else { //链表的结尾就是链表head节点的前一个节点 InsertNodeBefore(head, node); } } //在链表开头插入值为value的节点(插入到head节点之前) public void AddLast(T value) { AddLast(new CSharpLinkedListNode<T>(value)); } //在某个节点前面插入一个值 public void AddBefore(CSharpLinkedListNode<T> node, CSharpLinkedListNode<T> newNode) { InsertNodeBefore(node, node); //设置头节点 if (node == head) { head = newNode; } } //在某个节点后面插入一个值 public void AddAfter(CSharpLinkedListNode<T> node, CSharpLinkedListNode<T> newNode) { InsertNodeBefore(node.next, newNode); } public void Remove(CSharpLinkedListNode<T> node) { //链表仅有这个节点 if (node.next == node) { head = null; } else { node.prev.next = node.next; node.next.prev = node.prev; //如果删除的是开头 if (node == head) { head = head.next; } } //干掉node发出来的两根指针,使它成为垃圾 node.Invalidate(); count--; } //传入值的重载形式 public void Remove(T value) { var node = Find(value); if (node != null) { Remove(node); } } public void Print() { var current = First; do { Console.Write(current.item.ToString()); current = current.next; if(current != First) { Console.Write("->"); } } while (current != First); Console.Write("\n"); } public IEnumerator<T> GetEnumerator() { //传入链表本身 return new CSharpLinkedListEnumerator(this); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } //实现CSharpLinkedListEnumerator,继承IEnumerator<T>接口 public class CSharpLinkedListEnumerator : IEnumerator<T> { private T current; public T Current { get { return current; } } object IEnumerator.Current { get { return current; } } //数据源 private readonly CSharpLinkedList<T> list; //当前节点 private CSharpLinkedListNode<T> node; //当前位置 private int _position = -1; //初始化 public CSharpLinkedListEnumerator(CSharpLinkedList<T> data) { list = data; node = list.head; } //访问下一个 public bool MoveNext() { _position++; if (_position == list.count) { return false; } current = node.item; node = node.next; return true; } //不需要实现 public void Reset() { throw new NotImplementedException(); } //不需要代码,C#知道该如何做 public void Dispose() { } } } /// <summary> /// 双向链表节点 /// </summary> /// <typeparam name="T"></typeparam> public class CSharpLinkedListNode<T> { //这两个字段是私有的,防止用户不通过公共方法来胡乱篡改 internal CSharpLinkedListNode<T> next; internal CSharpLinkedListNode<T> prev; //节点的值 public T item { get; set; } public CSharpLinkedListNode(T value) { item = value; } //令一个节点成为垃圾 public void Invalidate() { this.prev = null; this.next = null; } } }