第一次听到链表这个词的时候觉得很酷,可能玩游戏觉得链是武器,固定思维了,哈哈。
接口:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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); } }
单向节点:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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; } } } }
单向链表:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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; } } } }
单向循环链表
区别看图↑
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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; } } }
其实大致实现差不多。