静态链表
早在还没有C语言的时候,只有Basic,Fortran等早期的编程语言,这些语言没有类似C语言的指针功能,但是他们又想描述链表,那怎么办呢?
我们不得不佩服古人们的智慧,有人想出了用数组来代替指针来描述单链表。
因此,我们把用数组描述单链表叫做静态链表,这种描述方法称为游标实现法。
线性表的静态链表存储结构:
#define MAXSIZE 1000
typedf struct
{
ElemType data; //数据
int cur; //游标(Cursor)
}Component,StaticLinkList[MAXSIZE];
最后一个元素的游标指向第一个有数据的下标地址,第一个元素的游标指向第一个没有数据的下标地址,其他的每一个元素都指向下一个元素的下标地址。
一、静态链表的初始化
对静态链表的初始化相当于初始化数组:
status InitList(StaticLinkList space)
{
int i;
for(i=0;i<MAXSIZE-1;i++)
space[i].cur=i+1;
space[MAXSIZE-1]=0;
return OK;
}
注意:
- 我们对第一个和最后一个元素进行特殊处理,它们的data不存放数据。
- 我们通常把为使用的数组元素称为备用链表。
- 数组的第一个元素,即下标为0的那个元素的cur存放备用链表第一个结点的下标地址。
- 数组的最后一个元素,即下标为MAXSIZE-1的那个元素的cur存放第一个有数值的元素的下标,相当于单链表的头结点作用。
- 数组的最后一个已使用的结点的游标为0.
二、静态链表的插入操作
首先时获取空闲分量的下标:
int Malloc_SLL(StaticLinkList space)
{
int i=space[0].cur;
if(space[0].cur)
space[0].cur=space[i].cur;
//更新头结点的游标为待使用结点的下一个
return i;
}
具体实现:
Status ListInsert(StaticLinkList L,int i,ElemType e)
{
int j,k,l;
k = MAXSIZE - 1; //数组的最后一个元素
if(i<1 || i>ListLength(L) + 1)
return ERROR;
j = Malloc_SLL(L); //获取第一个空闲分量的下标
L[0].cur = L[j].cur; //更新头结点
if(j)
{
L[j].data = e; //将数据存入空闲分量的数据域
for(l = 1;l<i-1;l++)
{
k = L[k].cur; //找到插入位置的前一个结点
}
L[j].cur = L[k].cur; //插入结点指向插入位置的下一个结点
L[k].cur = j; //将插入位置的前一个结点与插入结点链接
}
return OK;
}
三、静态链表的删除以及整表删除
/*删除在L中第i个数据元素*/
status ListDelete(StaticLinkList L, int i)
{
int j, k;
if (i<1 || i>Listlength(L))
return ERROR;
k = MAXSIZE - 1;
for (j = 1; j <= i - 1; j++)
{
k = L[k].cur; //找到删除结点的前一个结点
}
j = L[k].cur; //将删除结点的下标赋值给j
L[k].cur = L[j].cur; //将删除结点的前一个结点和后一个结点链接
Free_SLL(L, j);
return OK;
}
/*将下标为k的空闲结点会受到备用链表*/
void Free_SLL(StaticLinkList L, int j)
{
space[k].cur = space[0].cur; //将空闲结点与原先备用链表头结点链接
space[0].cur = k; //第一个结点指向备用链表头结点
}
/*返回L中数据元素个数*/
int Listlength(StaticLinkList L)
{
int j = 0; //元素个数
int i = L[MAXSIZE - 1].cur; //第一个数据元素的下标赋值给i
while (i)
{
i = L[i].cur; //用i的下一个结点给i赋值
j++;
}
return j;
}
静态链表的优缺点总结
优点
在插入和删除操作时,只需要修改游标,不需要移动元素,从而改进了在顺序存储结构中的插入和删除操作需要移动大量元素的缺点。
缺点
没有解决连续存储分配(数组)带来的表长难以确定的问题。
失去了顺序存储结构随机存取的特性。
总的来说呢,静态链表其实是为没有指针的编程语言设计的以中国实现单链表功能的方法。
尽管我们可以用单链表就不用静态链表了,但是这种思考方式是十分巧妙的,应该理解其思想,以备不时之需。