1>什么是静态链表
静态链表就是用数组描述的链表(这种描述方法叫游标实现法),我们让数组的每个元素都由一个结构体组成,结构体有两个成员,data和cursor,而cursor就相当于链表的next指针,用来存放后继元素在数组中的下标。
#define MAXSIZE 1000
//静态链表存储结构
typedef struct
{
char data;//数据
int cur;//游标
}Component,StaticLinkList[MAXSIZE];
2>静态链表的初始化
首先我们对第一个元素和最后一个元素进行初始化。让下标为0的元素的cur存放将要使用的空闲位置的下标,而最后一个元素的cur存放第一个有数值元素的下标。
bool InitList(StaticLinkList list)
{
int i;
for(i=0;i<MAXSIZE;i++)
list[i].cur = i+1;
list[MAXSIZE-1].cur = 0; //当前链表为空,所以最后一个元素的cur为0
return true;
}
3>静态链表的插入
我们先假设有这么几组数据
如图:(999的cur是1!!因为它存放的是第一个元素的下标!)
在插入之前我们先模拟动态链表中添加元素时使用的malloc();这里并不是真正的去申请空间,而是从静态链表中取得将要添加结点的下标
//若链表还有空间则返回将要插入结点的下标,否则返回0
int Malloc_SSL(StaticLinkList list)
{
int i = list[0].cur; //当前数组的第一个元素的cur存储值
// 就是将要使用的空闲位置
if(list[0].cur)
{
list[0].cur = list[i].cur; //这里要变更下一个空闲位置
}
return i;
}
很显然这段代码返回的值是6。
如果我们想在B和C之间再插入一个数据,那我们就得把B的cur改成5,再将新添加的数据(下标为5)的cur改成3。即如图:(999的cur是1!!因为它存放的是第一个元素的下标!)
实现代码如下:
// 这段代码是给静态链表的第i-1个元素后添加新元素
bool ListInsert(StaticLinkList list,int i,ElemType e)
{
int i,j,l;
k = MAXSIZE-1;
if(i < 1 || i > ListLength() + 1)
return false;
j = Malloc_SSL(L); //获取空闲下标
if(j)
{
list[i].data = e; //将数据值赋值给要空闲位置
for(l = 1;l<=i-1;l++)
k = list[k].cur; //找到第i-1个元素
list[i].cur = list[k].cur; //把第i-1个元素的cur赋值给新元素的cur
list[i].cur = j; //把新元素的下标赋值给第i-1个元素的cur;
return true;
}
return false;
}
4>静态链表的删除
这里和静态链表的插入类似的,我们模仿动态链表中使用的free();写一个函数Free_SSL();
void Free_SSL(StaticLinkList list,int k)
{
list[k].cur = list[0].cur; //把第一个元素的cur赋值给要删的元素
list[0].cur = k; //把要删除的分量下标赋值给第一个元素cur
}
如图以删除第一个结点为例:(如果删除的是第一个结点,那么要变更999的cur!!)
下面给出删除结点的具体代码:
//删除List中的第i个数据元素
bool ListDelete(StaticLinkList list,int i)
{
int j,k;
if(i<1 || i > ListLength(L))
return false;
k = MAXSIZE - 1;
for(j = 1;j <= i-1;j++)
k = list[k].cur;
j = list[k].cur;
list[k].cur = list[j].cur;
Free_SSL(L,j);
return true;
}
附加:
静态链表也可以像动态链表一样,计算数据元素个数
这里是代码:
//若链表为空则返回0,否则返回元素个数
int ListLeng(StaticLinkLint list)
{
int j = 0;
int i = list[MAXSIZE-1].cur;
while(i)
{
i = L[i].cur;
j++;
}
return true;
}
5>静态链表分析
优点:
在插入或删除时只需要改变游标即可,不需要移动大量元素。(这点动态链表也有)
缺点:
这点很明显,静态链表的长度一定,一旦初始化则不可改变。(而动态链表没有这个缺点)