一、静态链表
- 用数组描述的链表叫做 静态链表
//静态链表的存储结构
#define MAXSIZE 1000
typedef struct
{
ElemType data;
int cur; // 游标(Cursor),相当于单链表中的next指针,存放该元素的后继在数组中的下标,为0时表示无指向
} Component, StaticLinkList[MAXSIZE];
- 一般我们对数组第一个和最后一个元素作为特殊元素处理,不存数据。
- 通常把未使用的数组元素称为备用链表。
- 而数组第一个元素,即下标为0的元素的cur就存放备用链表的第一个结点的下标;而数组的最后一个元素的cur则存放第一个有数值的元素的下标,相当于单链表中的头结点作用,当整个链表为空时,则为0^2。
int init_list(StaticLinkList space)
{
int i;
for (i=0; i<MAXSIZE-1; i++)
space[i].cur = i+1;
space[MAXSIZE-1].cur = 0; //目前静态链表为空,最后一个元素的cur为0
return 0;
}
int list_length(StaticLinkList L)
{
int j = 0;
int i = L[MAXSIZE-1].cur;
while(i) {
i = L[i].cur;
j++;
}
return j;
}
假设我们已经将数据存入静态链表,比如分别存放着“甲”、“乙”、“丁”、“戊”、己”、“庚”等数据,则它将处于如图所示这种状态。
1.1 静态链表的插入
- 为了辨明数组中哪些分量未被使用,解决的办法是将所有未被使用过的及已被删除的分量用游标链成一个备用的链表,每当进行插入时,便可以从备用链表上取得第一个结点作为待插入的新结点。
int malloc_sll(StaticLinkList space)
{
int i = space[0].cur; //当前数据第一个元素的cur存的值,就是要返回的第一个备用空闲的下标
if (space[0].cur)
space[0].cur = space[i].cur; //由于要拿出一个分量来使用了,所以我们就得把它的下一个分量用来做备用
return i;
}
//在L中第i个元素之前插入新的数据元素e
int list_insert(StaticLinkList L, int i, ElemType e)
{
int j, k, l;
k = MAXSIZE - 1; //注意k首先是最后一个元素的下标
if (i < 1 || i > list_length(L) + 1)
return -1;
j = malloc_sll(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 0;
}
return -1;
}
1.2 静态链表的删除
void free_sll(StaticLinkList space, int k)
{
space[k].cur = space[0].cur; //把第一个元素cur赋值给要删除的分量cur
space[0].cur = k;
}
int list_delete(StaticLinkList L, int i)
{
int j, k;
if (i < 1 || i > list_length(L))
return -1;
k = MAXSIZE - 1;
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 0;
}
1.3 小结
- 静态链表其实是为了给没有指针的高级语言设计的一种实现单链表能力的方法。