一:链表简介
顾名思义就是链式结构,把一组内存不连续的数据(当然也可以连续),通过指针串联起来,链表中存储的数据被称为数据域,指针域也可以叫做链,是指储存下一个节点的内存地址
二:图解链表(画了一圈图,太难了,还是偷图吧~~~)
1.单链表:单链表的Next指向下一个节点的引用地址,尾节点的Next为空
2.双链表:与单链表不同的是,Node节点类中会有Next与Previous两个引用储存
3.环形链表:特点是尾节点的下一个几点会指向头结点(看似循环,实则还是可以有头节点与尾节点的)
4.链表的增删改查(以单链表示意)
增加
增加头结点:需要把新的节点的Next指向头结点,然后把这个新节点赋值给头结点
增加尾节点:把尾节点的Next指向新节点
增加中间节点:需要确定插入的节点下标(插入到哪里),这个时候需要把新节点的Next指向下标节点下一个的引用,把插入 下标上一个节点的引用指向新增节点
删除
删除头结点:把头结点改为头结点的下一个节点
删除尾节点:需遍历链表,找到尾节点的上一个节点,把尾节点赋值
删除中间节点:需把需要删除的节点的Next指针指向删除节点的Next
修改:这里的修改是指修改数据域的数据,这里就没有图了,只需要找到该节点,然后修改数据域即可
查找:链表的查找需要从头结点一节一节往下遍历frist.Next.Next.....
三:使用c#实现单链表
1.单链表功能清单
属性 | 作用 |
First | 获取头结点 |
Last | 获取尾节点 |
Count | 获取链表数量 |
IsEmpty | 判断链表是否为空 |
this[int index] | 索引器取数据 |
函数 | 作用 |
Clear() | 清空链表 |
Contains | 链表中是否包含该数据 |
AddFirst | 添加一个节点到首节点 |
AddLast | 添加一个节点到链表最后 |
Insert | 插入节点到参数Index处 |
Delete | 删除节点 |
DeleteAt | 根据下标删除节点 |
DeleteFirst | 删除头结点 |
DeleteLast() | 删除尾节点 |
Find | 查找节点 |
FindPrevious | 查找上一个节点 |
GetElement | 根据下标查找数据 |
IndexOf | 获取数据下标 |
2.定义接口预制功能清单ISingleLinkedListFunction
interface ISingleLinkedListFunction<T>
{
/// <summary>
/// 第一个节点
/// </summary>
SingleLinkedListNode<T> First { get; }
/// <summary>
/// 最后一个节点
/// </summary>
SingleLinkedListNode<T> Last { get; }
/// <summary>
/// 链表数量
/// </summary>
int Count { get; }
/// <summary>
/// 链表是否为空
/// </summary>
bool IsEmpty { get; }
/// <summary>
/// 清空链表
/// </summary>
void Clear();
/// <summary>
/// 链表中是否包含该数据
/// </summary>
/// <param name="value">验证数据项</param>
/// <returns></returns>
bool Contains(T value);
/// <summary>
/// 添加一个节点到节点起点
/// </summary>
/// <param name="value">节点数据</param>
/// <returns>返回Node节点</returns>
SingleLinkedListNode<T> AddFirst(T value);
/// <summary>
/// 添加一个节点到节点起点
/// </summary>
/// <param name="node">需要添加的节点</param>
/// <returns>添加的并不是参数节点,而是参数数据,返回添加的节点</returns>
SingleLinkedListNode<T> AddFirst(SingleLinkedListNode<T> node);
/// <summary>
/// 添加一个节点到链表最后
/// </summary>
/// <param name="value">节点数据</param>
/// <returns>节点</returns>
SingleLinkedListNode<T> AddLast(T value);
///<summary>
/// 添加一个节点到链表最后
/// </summary>
/// <param name="node">需要添加的节点</param>
/// <returns>添加的并不是参数节点,而是参数数据,返回添加的节点</returns>
SingleLinkedListNode<T> AddLast(SingleLinkedListNode<T> node);
/// <summary>
/// 插入一个节点到指定的下标出
/// </summary>
/// <param name="value">节点数据</param>
/// <param name="index">插入下标</param>
/// <returns>新增节点</returns>
SingleLinkedListNode<T> Insert(T value, int index);
/// <summary>
/// 插入一个节点到指定的下标出
/// </summary>
/// <param name="node">节点</param>
/// <param name="index">插入下标</param>
/// <returns>添加的并不是参数节点,而是参数数据,返回添加的节点</returns>
SingleLinkedListNode<T> Insert(SingleLinkedListNode<T> node, int index);
/// <summary>
/// 删除节点
/// </summary>
/// <param name="value">数据</param>
/// <returns>是否删除成功</returns>
bool Delete(T value);
/// <summary>
/// 删除节点
/// </summary>
/// <param name="index">删除的节点下标</param>
/// <returns>是否删除成功</returns>
bool DeleteAt(int index);
/// <summary>
/// 删除节点
/// </summary>
/// <param name="index">删除的节点</param>
/// <returns>是否删除成功</returns>
bool Delete(SingleLinkedListNode<T> node);
/// <summary>
/// 删除第一个节点
/// </summary>
/// <returns>是否删除成功</returns>
bool DeleteFirst();
/// <summary>
/// 删除最后一个节点
/// </summary>
/// <returns>是否删除成功</returns>
bool DeleteLast();
/// <summary>
/// 根据数据查找节点
/// </summary>
/// <param name="value">数据</param>
/// <returns>节点</returns>
SingleLinkedListNode<T> Find(T value);
/// <summary>
/// 根据数据查找上一个节点
/// </summary>
/// <param name="value">数据</param>
/// <returns>节点</returns>
SingleLinkedListNode<T> FindPrevious(T value);
/// <summary>
/// 索引器取数据
/// </summary>
/// <param name="index">下标</param>
/// <returns></returns>
T this[int index] { get; }
/// <summary>
/// 根据下标取数据
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
T GetElement(int index);
/// <summary>
/// 根据数据获取下标
/// </summary>
/// <param name="value">数据</param>
/// <returns>数据节点下标</returns>
int IndexOf(T value);
}
3.定义节点类SingleLinkedListNode
class SingleLinkedListNode<T>
{
public T Value { get; set; }
public SingleLinkedListNode<T> Next { get; set; }
public SingleLinkedListNode()
{
Value = default(T);
Next = null;
}
}
4.定义链表类SingleLinkedList,实现功能清单
class SingleLinkedList<T> : ISingleLinkedListFunction<T>
{
private SingleLinkedListNode<T> first = null;
/// <summary>
/// 头结点
/// </summary>
public SingleLinkedListNode<T> First
{
get
{
return first;
}
}
private SingleLinkedListNode<T> last = null;
/// <summary>
/// 尾节点
/// </summary>
public SingleLinkedListNode<T> Last
{
get
{
return last;
}
}
private int count;
/// <summary>
/// 链表节点数量
/// </summary>
public int Count
{
get
{
count = GetCount();
return count;
}
}
private bool isEmpty;
/// <summary>
/// 链表是否为空
/// </summary>
public bool IsEmpty
{
get
{
isEmpty = GetIsEmpty();
return isEmpty;
}
}
/// <summary>
/// 索引器
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public T this[int index]
{
get
{
if (index >= Count || index < 0)
{
return default(T);
}
SingleLinkedListNode<T> tempNode = first;
for (int i = 0; i < index; i++)
{
tempNode = tempNode.Next;
}
return tempNode.Value;
}
}
/// <summary>
/// 添加数据到链表首节点
/// </summary>
/// <param name="value">数据</param>
/// <returns>Node节点</returns>
public SingleLinkedListNode<T> AddFirst(T value)
{
SingleLinkedListNode<T> tempNode = new SingleLinkedListNode<T>();
tempNode.Value = value;
if (first == null)
{
first = tempNode;
last = tempNode;
}
else
{
tempNode.Next = first;
first = tempNode;
}
return tempNode;
}
/// <summary>
/// 添加节点到首节点(此时储存的并不是传递过来的数据地址,而是新建节点,赋值传过来节点的数据)
/// </summary>
/// <param name="node">数据节点</param>
/// <returns>真正添加的节点</returns>
public SingleLinkedListNode<T> AddFirst(SingleLinkedListNode<T> node)
{
SingleLinkedListNode<T> tempNode = CopyToFrom(node);
tempNode.Next = null;
if (first == null)
{
first = tempNode;
last = tempNode;
}
else
{
tempNode.Next = first;
first = tempNode;
}
return tempNode;
}
/// <summary>
/// 添加数据到尾节点
/// </summary>
/// <param name="value">数据</param>
/// <returns>Node节点</returns>
public SingleLinkedListNode<T> AddLast(T value)
{
SingleLinkedListNode<T> tempNode = new SingleLinkedListNode<T>();
tempNode.Value = value;
if (first == null)
{
first = tempNode;
last = tempNode;
}
else
{
last.Next = tempNode;
last = tempNode;
}
return tempNode;
}
/// <summary>
/// 添加尾节点(此时储存的并不是传递过来的数据地址,而是新建节点,赋值传过来节点的数据)
/// </summary>
/// <param name="node">数据节点</param>
/// <returns>返回真正添加的节点</returns>
public SingleLinkedListNode<T> AddLast(SingleLinkedListNode<T> node)
{
SingleLinkedListNode<T> tempNode = CopyToFrom(node);
tempNode.Next = null;
if (first == null)
{
first = tempNode;
last = tempNode;
}
else
{
last.Next = tempNode;
last = tempNode;
}
return tempNode;
}
/// <summary>
/// 清空链表
/// </summary>
public void Clear()
{
first = null;
last = null;
}
/// <summary>
/// 判断链表中是否有该数据
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public bool Contains(T value)
{
if (first == null)
{
return false;
}
SingleLinkedListNode<T> tempNode = first;
if (tempNode.Value.Equals(value))
{
return true;
}
while (true)
{
if (tempNode.Next != null)
{
if (tempNode.Value.Equals(value))
{
return true;
}
tempNode = tempNode.Next;
}
else
{
break;
}
}
return false;
}
/// <summary>
/// 删除第一个数据T的节点
/// </summary>
/// <param name="value"></param>
/// <returns>是否删除成功</returns>
public bool Delete(T value)
{
if (Contains(value))
{
SingleLinkedListNode<T> tempNode = first;
if (tempNode.Value.Equals(value))
{
first = first.Next;
return true;
}
SingleLinkedListNode<T> tempPrevious = null;
while (true)
{
if (tempNode.Next != null)
{
tempPrevious = tempNode;
tempNode = tempNode.Next;
if (tempNode.Value.Equals(value))
{
tempPrevious.Next = tempNode.Next;
return true;
}
}
else
{
break;
}
}
}
return false;
}
/// <summary>
/// 删除下标节点
/// </summary>
/// <param name="index">下标</param>
/// <returns>是否删除成功</returns>
public bool DeleteAt(int index)
{
if (index >= Count)
{
return false;
}
else
{
if (index == 0)
{
first = first.Next;
return true;
}
else
{
SingleLinkedListNode<T> tempNode = first;
//拿到需要删除节点的上一个节点
for (int i = 0; i < index - 1; i++)
{
tempNode = tempNode.Next;
}
tempNode.Next = tempNode.Next.Next;
return true;
}
}
}
/// <summary>
/// 删除节点
/// </summary>
/// <param name="node">删除的节点</param>
/// <returns>是否删除成功</returns>
public bool Delete(SingleLinkedListNode<T> node)
{
if (first == null)
{
return false;
}
else
{
SingleLinkedListNode<T> tempNode = first;
if (tempNode.Equals(node))
{
first = first.Next;
return true;
}
SingleLinkedListNode<T> tempPrevious = null;
while (true)
{
if (tempNode.Next != null)
{
tempPrevious = tempNode;
tempNode = tempNode.Next;
if (tempNode.Equals(node))
{
tempPrevious.Next = tempNode.Next;
return true;
}
}
else
{
break;
}
}
return false;
}
}
/// <summary>
/// 删除头节点
/// </summary>
/// <returns></returns>
public bool DeleteFirst()
{
if (first == null)
{
return false;
}
else
{
first = first.Next;
return true;
}
}
/// <summary>
/// 删除尾节点
/// </summary>
/// <returns></returns>
public bool DeleteLast()
{
if (first == null)
{
return false;
}
else
{
if (first == last)
{
last = null;
first = null;
}
else
{
//获取last的上一个节点
SingleLinkedListNode<T> tempNode = first;
SingleLinkedListNode<T> tempPrevious = null;
while (true)
{
if (tempNode.Next != null)
{
tempPrevious = tempNode;
tempNode = tempNode.Next;
}
else
{
tempPrevious.Next = null;
last = tempPrevious;
break;
}
}
}
return true;
}
}
/// <summary>
/// 查找数据所属节点
/// </summary>
/// <param name="value">数据</param>
/// <returns></returns>
public SingleLinkedListNode<T> Find(T value)
{
if (Contains(value))
{
SingleLinkedListNode<T> tempNode = first;
if (tempNode.Value.Equals(value))
{
return first;
}
while (true)
{
if (tempNode.Next != null)
{
if (tempNode.Value.Equals(value))
{
return tempNode;
}
tempNode = tempNode.Next;
}
else
{
break;
}
}
}
return null;
}
/// <summary>
/// 查找数据上一个节点
/// </summary>
/// <param name="value">数据</param>
/// <returns></returns>
public SingleLinkedListNode<T> FindPrevious(T value)
{
if (first == null)
{
return null;
}
SingleLinkedListNode<T> tempNode = first;
if (tempNode.Value.Equals(value))
{
return null;
}
SingleLinkedListNode<T> tempPrevious = null;
while (true)
{
if (tempNode.Next != null)
{
tempPrevious = tempNode;
tempNode = tempNode.Next;
if (tempNode.Value.Equals(value))
{
return tempPrevious;
}
}
else
{
break;
}
}
return null;
}
/// <summary>
/// 获取下标的数据域
/// </summary>
/// <param name="index">下标</param>
/// <returns>数据</returns>
public T GetElement(int index)
{
if (index >= Count)
{
return default(T);
}
else
{
if (index == 0)
{
return first.Value;
}
else
{
SingleLinkedListNode<T> tempNode = first;
//拿到需要删除节点的上一个节点
for (int i = 0; i < index; i++)
{
tempNode = tempNode.Next;
}
return tempNode.Value;
}
}
}
/// <summary>
/// 查找数据下标
/// </summary>
/// <param name="value">数据</param>
/// <returns>返回该数据第一次出现的下标</returns>
public int IndexOf(T value)
{
if (Contains(value))
{
int tempIndex = 0;
SingleLinkedListNode<T> tempNode = first;
if (tempNode.Value.Equals(value))
{
return tempIndex;
}
while (true)
{
if (tempNode.Next != null)
{
if (tempNode.Value.Equals(value))
{
return tempIndex;
}
tempNode = tempNode.Next;
tempIndex++;
}
else
{
break;
}
}
}
return -1;
}
/// <summary>
/// 插入数据到Index下标处
/// </summary>
/// <param name="value">数据</param>
/// <param name="index">下标</param>
/// <returns>Node节点</returns>
public SingleLinkedListNode<T> Insert(T value, int index)
{
if (index > Count || index < 0)
{
return null;
}
if (index == 0)
{
return AddFirst(value);
}
else if (index == Count)
{
return AddLast(value);
}
else
{
if (first == null) return null;
SingleLinkedListNode<T> tempNode = first;
for (int i = 0; i < index - 1; i++)
{
tempNode = tempNode.Next;
}
SingleLinkedListNode<T> newNode = new SingleLinkedListNode<T>();
newNode.Value = value;
newNode.Next = tempNode.Next;
tempNode.Next = newNode;
return newNode;
}
}
/// <summary>
/// 插入Node节点到Index下标节点
/// </summary>
/// <param name="node">数据节点</param>
/// <param name="index">下标</param>
/// <returns>真正添加的Node节点</returns>
public SingleLinkedListNode<T> Insert(SingleLinkedListNode<T> node, int index)
{
if (index > Count || index < 0)
{
return null;
}
if (index == 0)
{
return AddFirst(node);
}
else if (index == Count)
{
return AddLast(node);
}
else
{
if (first == null) return null;
SingleLinkedListNode<T> tempNode = first;
for (int i = 0; i < index - 1; i++)
{
tempNode = tempNode.Next;
}
SingleLinkedListNode<T> newNode = CopyToFrom(node);
newNode.Next = tempNode.Next;
tempNode.Next = newNode;
return newNode;
}
}
/// <summary>
/// 打印链表
/// </summary>
/// <returns></returns>
public override string ToString()
{
string str = "链表信息";
if (first == null)
{
Console.WriteLine("空链表");
return str;
}
SingleLinkedListNode<T> tempNode = first;
str += tempNode.Value.ToString();
while (true)
{
if (tempNode.Next != null)
{
tempNode = tempNode.Next;
str += tempNode.Value.ToString();
}
else
{
break;
}
}
Console.WriteLine(str);
return str;
}
/// <summary>
/// 获取链表数量
/// </summary>
/// <returns></returns>
private int GetCount()
{
if (first == null) return 0;
int tempCount = 1;
SingleLinkedListNode<T> tempNode = first;
while (true)
{
if (tempNode.Next != null)
{
tempNode = tempNode.Next;
tempCount++;
}
else
{
break;
}
}
return tempCount;
}
/// <summary>
/// 判断链表是否为空
/// </summary>
/// <returns></returns>
private bool GetIsEmpty()
{
return first == null;
}
/// <summary>
/// 为避免参数重复赋值(比如已经加了头结点,又加入了尾节点)
/// </summary>
/// <returns></returns>
private SingleLinkedListNode<T> CopyToFrom(SingleLinkedListNode<T> node)
{
SingleLinkedListNode<T> tempNode = new SingleLinkedListNode<T>();
tempNode.Value = node.Value;
tempNode.Next = tempNode.Next;
return tempNode;
}
}
5.使用此链表
class Program
{
static void Main(string[] args)
{
SingleLinkedList<int> singleLinkedList = new SingleLinkedList<int>();
SingleLinkedListNode<int> singleLinkedListNode = new SingleLinkedListNode<int>();
singleLinkedListNode.Value = 6;
//singleLinkedList.AddFirst(1);
//singleLinkedList.AddFirst(2);
//singleLinkedList.AddFirst(3);
//singleLinkedList.AddFirst(4);
//singleLinkedList.AddFirst(singleLinkedListNode);
singleLinkedList.AddLast(1);
singleLinkedList.AddLast(2);
singleLinkedList.AddLast(3);
singleLinkedList.AddLast(4);
singleLinkedList.Insert(singleLinkedListNode, 3);
//singleLinkedList.AddLast(4);
//singleLinkedList.AddLast(3);
//singleLinkedList.AddLast(2);
//singleLinkedList.AddLast(singleLinkedListNode);
Console.WriteLine("获取:" + singleLinkedList[1]);
Console.WriteLine("链表数量" + singleLinkedList.Count);
Console.WriteLine("链表是否为空" + singleLinkedList.IsEmpty);
singleLinkedList.ToString();
Console.ReadKey();
}
}
以上只贴出了,单链表的实现,双链表只是在节点类中添加上一个节点的引用,然后在实现链表功能中赋值即可,环形链表也是一样的,只需要把尾节点的Next指向头结点即可~
好了,文章到此就结束了,本文有什么错误的观点或者用法,希望各位看官能够及时提出,希望在自己积累知识的同时,能帮助到大家~