链表是一种线性数据结构,使用它能动态地存储一种结构数据。链表是n个数据元素的有限序列,其元素需要自己定义,既可以是一个整数或一个字符串。在计算机程序设计中,经常使用链表。
一、技术要点:
链表是一种重要的数据结构,该结构由节点组成。每个节点包含两部分数据,第一部分是节点本身的数据,第二部分是指向下一个节点的指针。对于单向链表,链表中存在两个特殊的节点,分别为“头结点”和“尾节点”。头结点本身没有数据,只存储下一个节点的指针,尾节点只存储数据。
下面是设计的一个节点类,代码如下:
public class ListNode
{
public ListNode(int NewValue)
{
Value = NewValue;
}
public ListNode Previous;
public ListNode Next;
public int Value;
}
其中,私有成员Value用于存储节点本身的数据,Next用于存储下一个节点的指针,Previous用于存储上一个节点的指针。对于链表的操作,无非是进行节点的查找、插入和删除。
1) 查找节点
在进行节点查找时,通常根据节点的数据查找节点。要实现节点的查找,首先需要解决的问题就是遍历链表中的所有节点。可以从链表头节点开始,利用循环的方式向下查找,如果当前节点指向的下一个节点不为空,则将下一个设置为当前节点。
2) 插入节点
插入节点需要考虑两种情况。第一种情况是在链表尾节点处插入节点,这种情况比较简单,只要将当前尾节点的Next指向新节点就可以了。第二种情况是在链表的中间位置插入节点,首先需要确定在哪个节点(当前节点)后插入新的节点,这就应该由用户确定了。然后需要记录当前节点的下一个节点,可以定义一个临时的节点进行记录。先将当前节点的下一个节点指向新添加的节点,再将新添加的节点的下一个节点指向临时节点,这样就可以了。
3) 删除节点
删除节点也需要考虑两种情况。第一种情况是删除尾节点,这种情况操作相对比较简单,首先找到尾节点之前的一个节点,将该节点指向的下一个节点设置为空,然后释放尾节点资源。第二种情况是删除链表中间部分的节点,首先需要找到当前节点的上一个节点,并定义一个临时节点PriorNode进行记录,然后再定义一个临时节点TempNode记录当前节点的下一个节点,最后将PriorNode的下一个节点指向TempNode,并释放当前节点。
二、代码实现(C#单向链表类库)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UnilateralismChainTable
{
//节点类
public class ListNode
{
public ListNode(int NewValue)
{
Value = NewValue;
}
public ListNode Previous;
public ListNode Next;
public int Value;
}
//初始化并定义指针变量
public class Clist
{
public Clist()
{
ListCountValue = 0;
Head = null;
Tail = null;
}
private ListNode Head;
private ListNode Tail;
private ListNode Current;
private int ListCountValue;
//尾部添加数据的代码如下:
public void Append(int DataValue)
{
ListNode NewNode = new ListNode(DataValue);
if (IsNull())
{
Head = NewNode;
Tail = NewNode;
}
else
{
Tail.Next = NewNode;
NewNode.Previous = Tail;
Tail = NewNode;
}
Current = NewNode;
ListCountValue += 1;
}
//删除当前数据的代码如下
public void Delete()
{
if (!IsNull())
{
if (IsBof())
{
Head = Current.Next;
Current = Head;
ListCountValue -= 1;
return;
}
if (IsEof())
{
Tail = Current.Previous;
Current = Tail;
ListCountValue -= 1;
return;
}
Current.Previous.Next = Current.Next;
Current = Current.Previous;
ListCountValue -= 1;
return;
}
}
//移动数据的代码如下
//向后移动一个数据
public void MoveNext()
{
if (!IsEof())
Current = Current.Next;
}
//向前移动一个数据
public void MovePrevious()
{
if(!IsBof())
Current=Current.Previous;
}
//移动到第一个数据
public void MoveFrist()
{
Current=Head;
}
//移动到最后一个数据
public void MoveLast()
{
Current=Tail;
}
//判断是否为空链表
public bool IsNull()
{
if(ListCountValue==0)
return true;
return false;
}
//判断是否达到尾部
public bool IsEof()
{
if(Current==Tail)
return true;
return false;
}
//判断是否到达头部
public bool IsBof()
{
if(Current==Head)
return true;
return false;
}
//获取节点值
public int GetCurrentValue()
{
return Current.Value;
}
//获取链表的数据个数
public int ListCount
{
get
{
return ListCountValue;
}
}
//清空链表
public void Clear()
{
MoveFrist();
while(!IsNull())
{
Delete();
}
}
//在当期位置前插入数据的代码如下:
public void Insert(int DataValue)
{
ListNode NewNode=new ListNode(DataValue);
if(IsNull())
{
Append(DataValue);
return;
}
if(IsBof())
{
//为头部插入
NewNode.Next=Head;
Head.Previous=NewNode;
Head=NewNode;
Current=Head;
ListCountValue+=1;
return;
}
//中间插入
NewNode.Next=Current;
NewNode.Previous=Current.Previous;
Current.Previous.Next=NewNode;
Current.Previous=NewNode;
Current=NewNode;
ListCountValue+=1;
}
//进行升序插入的代码如下:
public void InsertAscending(int InsertValue)
{
//参数InsertValue表示要插入的数据
if(IsNull())
{
Append(InsertValue);
return;
}
MoveFrist();
if(InsertValue<GetCurrentValue())
{
Insert(InsertValue);
return;
}
while(true)
{
if(InsertValue<GetCurrentValue())
{
Insert(InsertValue);
break;
}
if(IsEof())
{
Append(InsertValue);
break;
}
MoveNext();
}
}
//进行降序插入的代码如下:
public void InsertUnAscending(int InsertValue)
{
if(IsNull())
{
Append(InsertValue);
return;
}
MoveFrist();
if(InsertValue>GetCurrentValue())
{
Insert(InsertValue);
return;
}
while(true)
{
if(InsertValue>GetCurrentValue())
{
Insert(InsertValue);
break;
}
if(IsEof())
{
Append(InsertValue);
break;
}
MoveNext();
}
}
}
}
注:
1、此为单向链表类库,大家可以在以后的程序开发中使用。
2、类库命名为UnilateralismChainTable,默认类名为Class1(这里改为Clist)。