静态链表
用数组描述的链表叫做静态链表该数据下标都对应一个data(存放数据元素)和一个cur(存放该元素的后继在数组中的下标)
//线性表的静态链表存储结构
#define MAXSIZE 1000 //假设链表的最大长度为1000
typedef struct
{
ElemTypedata;
Int cur;
}Comment,StaticLinkList[Maxsize];
数组的第一个元素,即下标为0的元素的cur就存放备用链表(未被使用的数组元素)的第一个结点的下标;而数组的最后一个元素的cur则存放第一个有数值的元素的下标。
静态链表的插入
用静态模拟动态链表结构的存储空间的分配,需要,无用时申请释放。
为辨明数组中数组中哪些分量未被使用,解决的办法是将所有未被使用过的及已被删除分量用游标链成一个备用的链表,每当进行插入时,便可以从备用链表上去的第一个结点作为带插入的新结点
//若备用空间链表非空,则返回分配的结点下标,否则返回0
int Malloc_SLL(StaticLinkList space)
{
int I = space[0].cur; //当前数组第一个元素的cur存的值
if(space[0].cur)
{
space[0].cur = space[i].cur;
}
return i;
}
这段代码一方面的作用就是返回一个下标值,这个值就是数组头元素的cur存的第一个空闲的下标,从图例看来,就是返回7.如果下表为7的分量要准备使用了,就把分量7的cur值赋给头元素,也就是8给space[0].cur
//在L中第i个元素之前插入新的数据元素e
Status ListInsert(StaticLinkList L, int i, ElemType e)
{
int j,k,l;
K = MAX_SIZE – 1; //K首先是最后一个元素的下标
if(i < 1|| i > ListLength(L) + 1)
{
return ERROR;
}
j = Malloc_SSL(L); //获得空闲分量的下标
if(j)
{
L[j].data = e; //将数据复制给此分量data
for(l = 1; l <= i – 1; l++) //找到第i个元素之前的位置
{
K = L[K].cur;
}
L[j].cur = L[k].cur; //把第i个元素之前的cur赋值给新元素的cur
L[k].cur = j; //把新元素的下标赋值给第i个元素之前元素的cur
return OK;
}
return ERROR;
}
静态链表的删除操作
//删除在L中第i个数据元素
Status ListDelete(StaticLinkList L, int i)
{
int j,k;
K = MAX_SIZE – 1; //K首先是最后一个元素的下标
if(i < 1|| i > ListLength(L) )
{
return ERROR;
}
for(j = 1; j <= i – 1; j++)
{
K = L[k].cur;
}
j = L[k].cur;
L[k].cur = L[j].cur;
Free_SSL(L,j);
return OK;
}
//初始条件:静态链表L已存在。 操作结果:返回L中数据元素个数
int ListLength(StaticLinkList L)
{
int j = 0;
int i = L[MAXSIZE - 1].cur;
while(i)
{
i=L[i].cur;
j++;
}
return j;
}
静态链表优缺点
优点:
l 在插入和删除操作时,只需要修改游标,不需要移动元素,从而改进了在顺序存储结构中的插入和删除操作需要移动大量元素的缺点
缺点:
l 没有解决连续存储分配带来的表长难以确定的问题
l 失去了顺序存储结构随机存储的特性