用数组描述的链表叫做静态链表。还有叫法是游标实现法。
为了方便使用,我们可以把数组建立的大一些。
另外我们对数组的第一个和最后一个元素作为特殊元素处理,不存数据。我们通常把未使用的数组元素称为备用链表。而数组第一个元素,即下标为 0 的元素的 cur 就存放备用链表的第一个结点的下标;而数组的最后一个元素的 cur 则存放第一个有数值的元素的下标,相当于单链表中的头结点的作用。
public class Node<T>
{
public T data;//数据
public int cur;//游标
public Node()
{
this.data = default(T);
}
}
public class StaticLinkList<T>
{
private int _length = 0;
public int Length
{
get
{
return _length;
}
}
private static readonly int MaxSize = 10;
private static Node<T>[] _array;//头尾位置留用
/// <summary>
/// 构造静态链表
/// </summary>
public StaticLinkList()
{
_array = new Node<T>[MaxSize];
Init();
}
/// <summary>
/// 初始化静态链表
/// </summary>
private void Init()
{
for (int i = 0; i < MaxSize; i++)
{
_array[i] = new Node<T>();
_array[i].cur = i + 1;
}
_array[MaxSize - 1].cur = 1;
}
/// <summary>
/// 返回第一个可用的位置
/// </summary>
/// <returns></returns>
private int Malloc()
{
int i = _array[0].cur;
if (i == MaxSize - 1)
{
Console.WriteLine("StaticLinkList is full!");
return -1;
}
if (i > 0)
{
_array[0].cur = _array[i].cur;
}
return i;
}
/// <summary>
/// 释放该位置
/// </summary>
/// <param name="index"></param>
private void Free(int index)
{
_array[index].cur = _array[0].cur;
_array[index].data = default(T);
_array[0].cur = index;
}
private void AddLength()
{
_length++;
}
private void DeleteLength()
{
_length--;
}
/// <summary>
/// 输出静态链表
/// </summary>
public void Display()
{
for (int i = 0; i < _array.Length; i++)
{
Node<T> item = _array[i];
string dataStr = "Null";
if (item.data != null)
{
dataStr = item.data.ToString();
}
Console.WriteLine("下标:" + i.ToString() + ",数据:" + dataStr + ",游标:" + item.cur.ToString());
}
}
/// <summary>
/// 添加一个元素
/// </summary>
/// <param name="item"></param>
public void Add(T item)
{
int temp = Malloc();
if (temp < 0)
{
Console.WriteLine("Add item fail");
return;
}
_array[temp].data = item;
_array[temp].cur = _array[0].cur;
AddLength();
}
/// <summary>
/// 静态链表插入元素
/// </summary>
/// <param name="item">要插入的数据</param>
/// <param name="index">插入的位置</param>
public void Insert(T item, int index)
{
if (index < 1 || index > Length + 1)
{
return;
}
int free_Length = Malloc();
if (free_Length < 0)
{
Console.WriteLine("Insert item fail");
return;
}
int temp = MaxSize - 1;
_array[free_Length].data = item;
for (int i = 1; i <= index - 1; i++)
{
temp = _array[temp].cur;
}
_array[free_Length].cur = _array[temp].cur;
_array[temp].cur = free_Length;
AddLength();
}
/// <summary>
/// 删除该位置元素
/// </summary>
/// <param name="index">删除的位置</param>
public void Delete(int index)
{
if (index < 1 || index > Length)
{
return;
}
int temp = MaxSize - 1;
for (int i = 1; i <= index - 1; i++)
{
temp = _array[temp].cur;
}
int j = _array[temp].cur;
_array[temp].cur = _array[j].cur;
Free(j);
DeleteLength();
}
}
静态链表优缺点
优点:
在插入个删除操作时,只需要修改游标,不需要移动元素,从而改进了在顺序存储结构中的插入和删除操作需要移动大量元素的缺点。
缺点:
①没有解决连续存储分配带来的表长难以确定的问题。
②失去了顺序存储结构随机存取的特性。