一、解析
我们把这种用数组描述的链表叫做静态链表,又称游标实现法。
实现方法:
首先让数组的元素都是有两个数据域组成,data和cur。也就是说,数组的每个下标都对应一个data和一个cur。数据域data,用来存放数据元素,也就是通常我们要处理的数;而游标cur相当于单链表中的next指针,存放该元素的后继在数组中的下标。
对于数组的第一个和最后一个元素作为特殊元素处理,不存数据。通常把未使用的数组元素称为备用链表。而数组第一个元素,即下标为0的元素的cur就存放备用链表的第一个结点的下标;而数组的最后一个元素的cur则存放第一个有数值的元素的下标,相当于链表中的头结点作用,当整个链表为空时,则为02。
注意:
1. 对于不提供结构struct的程序设计语言,可以使用一对并行数组data和cur来处理。
2. 有些书中把数组的第二个元素用来作为头结点,实现原理相同,只不过是取得存放位置不同。
静态链表c程序实现
用数组来代替指针,描述单链表,叫做静态链表。其中数组的元素都是由两个数据域组成,data和cur,data用来存放数据,cur相当于单链表中的next指针,存放该元素的后继在数组中的下标,我们把cur称为游标,因此,静态链表又叫游标实现法。
我们把静态链表中未被使用的数组元素称为备用链表。我们对数组的第一个和最后一个元素做特殊处理,不存数据。其中,数组的第一个元素,即下标为0的元素的cur用来存放备用链表的第一个结点的下标;而数组的最后一个元素的cur则存放第一个有数值的元素的下标,相当于单链表中的头结点。
下面给出一个例子,假设我们的静态链表存放了“甲”,“乙”,“丙”,“丁”四个数据,静态链表的长度为1000,则该静态链表如下表所示。下表中红色的“5”表示如果再往静态链表中存放一个数据,将存放在下标为5的位置。红色的“0”表示下一个位置数据位空,即“丁”是目前静态链表中最后一个元素。红色的“1”表示静态链表中下标为1处的“甲”是本静态链表的第一个元素。
Data |
|
甲 |
乙 |
丙 |
丁 |
|
|
|
|
Cur |
5 |
2 |
3 |
4 |
0 |
|
|
|
1 |
下标 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
。。。 |
999 |
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 1000
typedef int ElemType;
typedef struct
{
ElemType data;
int cur;
}StaticLinkList[MAXSIZE];
typedef enum
{
ERROR=-1,
OK=1,
}Status;
/*将下标为k的空闲结点回收到备用链表*/
void Free_SSL(StaticLinkList space,int k)
{
space[k].cur=space[0].cur;
space[0].cur=k;
}
/*返回L中数据元素个数*/
int ListLength(StaticLinkList L)
{
int j=0;
int i=L[MAXSIZE-1].cur;
while(i)
{
i=L[i].cur;
j++;
}
return j;
}
/*将一维数组space中各分量链成一个备用链表*/
Status InitList(StaticLinkList space)
{
int i;
for(i=0;i<MAXSIZE - 1;i++)
{
space[i].cur=i+1;
}
space[MAXSIZE-1].cur=0;
return OK;
}
/*若备用链表非空,则返回分配的结点下标,否则返回0*/
int Malloc_SLL(StaticLinkList space)
{
int i=space[0].cur;
if(space[0].cur)
{
space[0].cur=space[i].cur;
}
return i;
}
/*在L中第i个元素前插入新的数据元素e*/
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);
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;
}
return ERROR;
}
/*删除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;
L[k].cur=L[j].cur;
Free_SSL(L,j);
return OK;
}
/*打印L中各元素*/
void ListDisp(StaticLinkList L)
{
int i=L[MAXSIZE-1].cur;
while(i!=0)
{
printf("%d ",L[i].data);
i=L[i].cur;
}
printf("\n");
}
int main(void)
{
StaticLinkList test;
InitList(test);
printf("after InitList,StaticLinkList test is:");
ListDisp(test);
int i;
for(i=0;i<10;i++)
{
ListInsert(test,i,i*10);
printf("after ListInsert,StaticLinkList test is:");
ListDisp(test);
}
for(i=0;i<10;i++)
{
ListDelete(test,1);
printf("after ListDelete,StaticLinkList test is:");
ListDisp(test);
}
return EXIT_SUCCESS;
}