线性表(链式实现)
背景
今天复习 以链式存储方式 实现的线性表结构,简称为链表。这里我们只介绍单链表
基本理论
-
以链式存储方式实现的线性表结构,简称为链表。
-
链表与顺序结构不同,顺序存储结构要求线性表逻辑结构与物理结构相同,而对于链表,逻辑结构与物理结构可以相同也可以不同
-
单链表:每个结点只含有一个指针域的链表,其中pHead指针指向第一个结点,是我们操作的起点。其存储结构如下:
-
其需要实现的操作如下(与顺序结构线性表相同):
代码实现:
- 链表结点:
/// <summary>
/// 链表结点
/// </summary>
/// <typeparam name="T">结点存储数据的数据类型</typeparam>
public class SNode<T>
{
/// <summary>
/// 数据域
/// </summary>
public T Data { get; set; }
/// <summary>
/// 指针域
/// </summary>
public SNode<T> Next { get; set; }
public SNode(T data)
{
Data = data;
Next = null;
}
public SNode(T data, SNode<T> next)
{
Data = data;
Next = next;
}
}
- 链表操作实现:
/// <summary>
/// 单链表实现
/// </summary>
/// <typeparam name="T">链表存储数据的类型</typeparam>
public class SLinkList<T> : ILinearList<T> where T : IComparable<T>
{
private SNode<T> pHead;
/// <summary>
/// 获取元素个数
/// </summary>
public int Length { get; private set; }
/// <summary>
/// 初始化单链表
/// </summary>
public SLinkList()
{
Length = 0;
pHead = null;
}
/// <summary>
/// 获取对应索引处的结点
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public SNode<T> Locate(int index)
{
if (index < 0 || index > Length - 1)
throw new IndexOutOfRangeException();
SNode<T> temp = pHead;
for (int i = 0; i < index; i++)
{
temp = temp.Next;
}
return temp;
}
/// <summary>
/// 获取或设置对应索引处结点的数据
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public T this[int index]
{
get
{
if (index < 0 || index > Length - 1)
throw new IndexOutOfRangeException();
return Locate(index).Data;
}
set
{
if (index < 0 || index > Length - 1)
throw new IndexOutOfRangeException();
Locate(index).Data = value;
}
}
/// <summary>
/// 向单链表头部插入数据
/// </summary>
/// <param name="data"></param>
public void InsertAtFirst(T data)
{
pHead = new SNode<T>(data, pHead);
Length++;
}
/// <summary>
/// 向单链表尾部插入数据
/// </summary>
/// <param name="data"></param>
public void InsertAtRear(T data)
{
if (Length == 0)
pHead = new SNode<T>(data);
else
Locate(Length - 1).Next = new SNode<T>(data);
Length++;
}
/// <summary>
/// 向单链表对应索引处插入数据
/// </summary>
/// <param name="index"></param>
/// <param name="data"></param>
public void Insert(int index, T data)
{
if (index < 0 || index > Length)
throw new IndexOutOfRangeException();
if (index == 0)
InsertAtFirst(data);
else if (index == Length)
InsertAtRear(data);
else
{
Locate(index - 1).Next = new SNode<T>(data, Locate(index));
Length++;
}
}
/// <summary>
/// 判断单链表是否为空
/// </summary>
/// <returns></returns>
public bool IsEmpty()
{
return Length == 0;
}
/// <summary>
/// 清除单链表
/// </summary>
public void Clear()
{
pHead = null;
Length = 0;
}
/// <summary>
/// 移除对应索引处的结点
/// </summary>
/// <param name="index"></param>
public void Remove(int index)
{
if (index < 0 || index > Length - 1)
throw new IndexOutOfRangeException();
if (index == 0)
pHead = pHead.Next;
else
Locate(index - 1).Next = Locate(index + 1);
Length--;
}
/// <summary>
/// 查找单链表中是否存在对应数据,若有返回其索引;若没有,返回-1
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public int Search(T data)
{
SNode<T> temp = pHead;
int i;
for (i = 0; i < Length; i++)
{
if (Locate(i).Data.CompareTo(data) == 0)
break;
temp = temp.Next;
}
return i == Length ? -1 : i;
}
}