第一次聽到鏈表這個詞的時候覺得很酷,可能玩游戲覺得鏈是武器,固定思維了,哈哈。
接口:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _001_線性表 { interface IListDS<T> { int GetLength(); void Clear(); bool IsEmpty(); void Add(T item); void Insert(T item, int index); T Delete(int index); T this[int index] { get; } T GetEle(int index); int Locate(T value); } }
單向節點:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _001_線性表 { /// <summary> /// 單鏈表節點 /// </summary> /// <typeparam name="T"></typeparam> class Node<T> { private T data;//存儲數據 private Node<T> next;//指針 用來指向下一個元素 public Node(T value) { data = value; next = null; } public Node(T value,Node<T> next) { this.data = value; this.next = next; } public Node(Node<T> next) { this.next = next; } public Node() { this.data = default(T); this.next = null; } public T Data { get { return data; } set { data = value; } } public Node<T> Next { get { return next; } set { next = value; } } } }
單向鏈表:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _001_線性表 { /// <summary> /// 單鏈表 /// </summary> /// <typeparam name="T"></typeparam> class LinkList<T> : IListDS<T> { private Node<T> head;//存儲一個頭結點 public LinkList() { head = null; } public T this[int index] => GetEle(index); /// <summary> /// 添加節點 /// </summary> /// <param name="item"></param> public void Add(T item) { Node<T> newNode = new Node<T>(item);//根據新的數據創建一個新的節點 //如果頭結點為空,那么這個新的節點就是頭節點 if (IsEmpty()) { head = newNode; return; } else { //把新來的結點放到 鏈表的尾部 //要訪問到鏈表的尾部結點 Node<T> temp = head; while (temp.Next != null) { temp = temp.Next; } temp.Next = newNode; } } /// <summary> /// 清空 /// </summary> public void Clear() { head = null; } /// <summary> /// 刪除節點 /// </summary> /// <param name="index"></param> /// <returns></returns> public T Delete(int index) { T data = default(T); if (index == 0) //刪除頭節點 { data = head.Data; head = head.Next; } else { Node<T> pre = head; for (int i = 1; i < index-1; i++) { //讓pre向后移動一個位置 pre = pre.Next; } Node<T> Del = pre.Next; //得到要刪除的節點 data = Del.Data; //得到刪除節點的數據 Node<T> atf = Del.Next; // 得到刪除節點的之后的節點 pre.Next = atf; //連接 前后節點 } return data; } /// <summary> /// 獲取指定位置元素 /// </summary> /// <param name="index"></param> /// <returns></returns> public T GetEle(int index) { Node<T> temp = head; for (int i = 0; i < index; i++) { temp = temp.Next; } return temp.Data; } /// <summary> /// 獲取長度 /// </summary> /// <returns></returns> public int GetLength() { if (IsEmpty()) { return 0; } Node<T> temp = head; int count = 1; while (temp.Next != null) { count++; temp = temp.Next; } return count; } /// <summary> /// 插入節點 /// </summary> /// <param name="item"></param> /// <param name="index"></param> public void Insert(T item, int index) { Node<T> newNode = new Node<T>(item); //新節點 if (index == 0)//插入到頭節點 { newNode.Next = head; head = newNode; } else { Node<T> pre = head; for (int i = 1; i <=index-1; i++) { //讓temp向后移動一個位置 pre = pre.Next; } Node<T> preNode = pre; //要插入的 前面節點 Node<T> afterNode = pre.Next; //要插入的 后面節點 preNode.Next = newNode; //前節點的尾巴 連接 新節點 newNode.Next = afterNode; //新節點的尾巴 連接 后面的節點 } } /// <summary> /// 是否為空 /// </summary> /// <returns></returns> public bool IsEmpty() { return head == null; } public int Locate(T value) { Node<T> temp = head; if (IsEmpty()) { return -1; } else { int index = 0; while (true) { if (temp.Data.Equals(value)) //相同就直接返回 { return index; } else { if (temp.Next != null) //下個節點不為空 { index++; temp = temp.Next; } else //為空 { break; } } } return -1; } } } }
單向循環鏈表
區別看圖↑

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _001_線性表 { /// <summary> /// 單鏈循環鏈表 /// </summary> /// <typeparam name="T"></typeparam> class LoopLinkList<T> : IListDS<T> { private Node<T> head; public Node<T> Head { set { head = value; head.Next = head; } get { return head; } } public T this[int index] => GetEle(index); /* public Node<T> this[int index] { set { if (IsEmpty()) throw new Exception("鏈表為空"); if (index < 0 || index > this.GetLength() - 1) throw new Exception("索引超出鏈表長度"); Node<T> node = head; for (int i = 0; i < index; i++) { node = node.Next; } node.Data = value.Data; node.Next = value.Next; } get { if (index < 0 || index > this.GetLength() - 1) throw new Exception("索引超出鏈表長度"); Node<T> node = head; for (int i = 0; i < index; i++) { node = node.Next; } return node; } } */ /// <summary> /// 在末端添加一個新節點 /// </summary> /// <param name="item"></param> public void Add(T item) { Node<T> newNode = new Node<T>(item); if (IsEmpty()) //判斷是否為空,物是人非 { this.Head = newNode; return; } else { Node<T> temp = head; while (temp.Next != head) //循環 判斷是否為頭部,是就跳出循環 { temp = temp.Next; } temp.Next = newNode; newNode.Next = head; } } /// <summary> /// 清空表元素 /// </summary> public void Clear() { head = null; } /// <summary> /// 刪除鏈表指定位置的元素 /// </summary> /// <param name="index"></param> /// <returns></returns> public T Delete(int index) { T data = default(T); if (IsEmpty()) throw new Exception("鏈表為空,沒有可清除的項"); if (index < 0 || index > this.GetLength() - 1) throw new Exception("給定索引超出鏈表長度"); Node<T> preNode = head; if (index == 0) { while (preNode.Next!=head) { preNode = preNode.Next; } this.head = head.Next; data=preNode.Next.Data; preNode.Next = this.head; } else { for (int i = 1; i < index-1; i++) { preNode = preNode.Next; } preNode.Next = preNode.Next.Next; } return data; } public T GetEle(int index) { if (index < 0 || index > this.GetLength() - 1) throw new Exception("索引超出鏈表長度"); Node<T> node = head; for (int i = 0; i < index; i++) { node = node.Next; } return node.Data; } /// <summary> /// 獲取鏈表長度 /// </summary> /// <returns></returns> public int GetLength() { if (IsEmpty()) { return 0; } else { int length = 1; Node<T> temp = head; while (temp.Next!=head) { temp = temp.Next; length++; } return length; } } /// <summary> /// 在鏈表指定的位置插入一個新節點 /// </summary> /// <param name="item"></param> /// <param name="index"></param> public void Insert(T item, int index) { if (IsEmpty()) throw new Exception("數據鏈表為空"); if (index < 0 || index > this.GetLength()) throw new Exception("給定索引超出鏈表長度"); Node<T> newNode = new Node<T>(item); Node<T> preNode = head; if (index == 0) //等於零 先找到 鏈表中 head的前一個節點 這個節點連接 head { while (preNode.Next!=head) { preNode = preNode.Next; } preNode.Next = newNode; newNode.Next = this.head; return; } else { for (int i = 1; i < index-1; i++) { preNode = preNode.Next; } Node<T> atfNode= preNode.Next; preNode.Next = newNode; newNode.Next = atfNode; } } /// <summary> /// 清空是否為空 /// </summary> /// <returns></returns> public bool IsEmpty() { return head == null; } /// <summary> /// 根據給定的值查找鏈表中哪個元素為這個值,如果鏈表中存在兩個元素值相同,則取排在鏈表前面的元素 /// </summary> /// <param name="value"></param> /// <returns></returns> public int Locate(T value) { if (IsEmpty()) throw new Exception("鏈表為空"); Node<T> preNode = head; int index = 0; while (true) { if (!preNode.Data.Equals(value)) { if (preNode.Next != head) { index++; preNode = preNode.Next; } else { break; } } else { return index; } } return -1; } } }
其實大致實現差不多。