静态链表
用数组描述的链表是静态链表,描述的方法是游标实现法。
游标实现法(游标相当于单链表中的next指针,存放该元素的后继在数组中的下标):
有两个位置需要注意,第一个是数据结构存放最后一个数据的游标存放第一个有数据的下标。第二个是数据结构存放第一个数据的游标存放第一个没有数据的下标。
一般通过这两个特殊的位置来定位数据。 会用下标为0的找到第一个数据为空的游标,通过最后一个下标找到第一个有数据的游标。
静态链表结构体
#define MAXSIZE 1000
typedef struct
{
ElemType data;
int cur;//游标
}Component,StaticLinkList[MAXSIZE];
静态链表初始化:
屁股指向头,头指向第一个没有数据的地方,头没有数据,通过游标找到数据找到下一个下标。
没有被使用的数组元素称为备用链表.
头游标的作用类似头指针,第一个不存放数据。结尾指向第一个有数据的游标。
Status InitList(StaticLinkList space)
{
int i;
for(i=0;i<MAXSIZE-1;i++)
{
space[i].cur=i+1;//游标初始化
}
space[MAXSIZE-1].cur=0;
return 1;
}
静态链表的插入:
//获取空闲第一个分量的下标
int Malloc_SLL(StaticLinkList space)
{
//把游标理解成指针
int i=space[0].cur;//获得指向第一个不为0的游标/指针
if(space[0].cur)//如果游标不为空
space[0].cur=space[i].cur;//第一个元素的游标指向第I个元素的游标指向(指针)
return i;//返回不为0的位置的游标
}
//插入操作:在静态链表L中第i个元素之间插入新的元素e
Status ListInsert(StaticLinkList L,int i,Elemtype e)
{
int j,k,i;
k=MAXSIZE-1;//数组的最后一个元素,指向第一个不为空的元素
if(i<1||i>ListLenth(L)+1)//简单的错误处理
{
return ERROR;
}
j=Malloc_SLL(L);//获取第一个空闲的位置
if(j)
{
L[j].data=e;//插入数据
for(l=1;l<=i-1;l++)//查询i-1数据的游标
{
k=L[k].cur;
}
L[j].cur=L[k].cur;
L[k].cur=j;
return OK;
}
return ERROR;
}
静态链表的删除
//删除链表中第i个数据元素
Status ListDelte(StaticLinkList L,int i)
{
int j,k;
k=MAXSIZE-1;//数组的最后一个元素,指向第一个不为空的元素
if(i<1||i>ListLenth(L)+1)//简单的错误处理
{
return ERROR;
}
j=Malloc_SLL(L);//获取第一个空闲的位置
for(j=1;j<=i-1;j++)
{
k=L[k].cur;
}
j=L[k].cur;
L[k].cur=L[j].cur;
Free_SLL(L,j);
return OK;
}
return ERROR;
}
//将下标为k的结点回收备用链表
void Free_SLL(StaticLinkList L,int i)
{
space[k].cur=space[0].cur;
space[0].cur=k;
}
返回静态链表中的元素的个数
int ListLength(StaticLinkList L)
{
int i,j;
i=L[MAXSIZE-1].cur;//
while(i)
{
i=L[i].cur;//不断指向下一个游标
j++;
}
return j;
}
静态链表的优缺点
优点:
只需要修改游标,不需要移动元素,改进了顺序存储结构中插入和删除要移动大量数据的情况。
缺点:
没有解决连续存储分配(数组)带来的表长难以确定的问题。
失去了随机存取结构的特性。
总结:静态链表是为了给没有指针语言的设计。