静态链表顾名思义就是用静态数组的方式来模拟一个链表的实现,这个在没有指针类型的高级机器语言会出现,但是用途感觉还是很少的,由于是借助于一个固定长度的数组来描述线性表的链式存储结构,灵活度比较低的。
和链表的一样,
adt
中含有数据域data
和指针域next
,但是静态链表中的指针常常被称之为游标
,也就是cur
,和顺序表相同初始化之前要预先分配一块连续的内存空间。
静态链表图示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J8kL2Oaq-1653238705239)(C:\Users\达芬奇\AppData\Roaming\Typora\typora-user-images\image-20220522235316773.png)]
基本思想
由于王道第二章对这个静态链表描述较少,这里做一点点补充吧。
首先就是第一点,通常会将静态链表的0位置的结点设置为整个链表的头结点,用他来对已经申请的结点进行管理。
头结点的特点
数据域中不存数据,游标的值尾第一个申请结点所对应的数组下标,若是该静态链表还未申请结点来存放数据,那么其游标的值设为-1表示该静态链表为空
那么未被分配空间的结点要怎么办呢?
我们这里会让数组位置1空出来,来作为未被分配结点的管理结点pool,其数据域同样不放入数据,其cur指向的点为未被分配数据的第一个结点,也就是,王道图为更加简化版没有设置一个管理未被分配区(也被称为静态链表的备用区),也就是说pool这个结点充当一个备用区的头结点的作用,其中不包含数据且其游标值为第一个未申请结点对应的下标值(当表中已经没有未被申请的节点后,其cur设置为0,表示链表已满)
具体实现
定义:
#define MAXSIZE 20
typedef char ELemType;
//静态链表的定义
typedef struct {
ELemType data;
int cur;
}SLinkList[MAXSIZE];
初始化:
//静态链表的初始化
void InitSList(SLinkList space) {
//先要初始化备用空间pool(下标从1-maxsize-1)由于一开始都没分配空间
//然后吧0位置的cur设为-1,因为一开始没有结点含有数据
//还有就是备用区最后一个空间后面再无可以用的空间游标设为0
for (int i = 1; i < MAXSIZE; ++i) {
space[i].cur = i + 1;
}
space[MAXSIZE - 1].cur = 0;
space[0].cur = -1;
}:
申请结点:
//申请结点
int MallocKnot(SLinkList space) {
int i = space[1].cur;//表示从备用区头结点的游标即下一个空数据结点
if (i != 0) {
//说明还有空闲结点
//更改头指针指向表示指向下一个空的结点
space[1].cur = space[i].cur;
}
return i;//返回新申请的空间的数组下标的
}
头插法:
//头插法
int InsertKnot(SLinkList space, ELemType ee) {
int tmp = MallocKnot(space);
if (tmp == 0) {
//申请空间失败
printf("已满");
return 0;
}
//成功
space[tmp].data = ee;
if (space[0].cur == -1) {
space[0].cur = tmp;
space[tmp].cur = -1;
}
else
{
//之前已经有数据节点了
//因为后面的结点完全不知道前面的结点情况
//所以新插入结点的游标直接让头节点游标赋值即可
space[tmp].cur = space[0].cur;
space[0].cur = tmp;
}
return 1;
}
删除结点(头部):
//删除结点(在头部)
int Delete(SLinkList space) {
int tmp = space[0].cur;
space[0].cur = space[tmp].cur;//逻辑上删除
//要重新分配一下备用区pool
space[tmp].cur = space[1].cur;
space[1].cur = tmp;
}
打印链表:
//结点数据显示
void showlist(SLinkList space) {
int i = space[0].cur;
while (i!=-1)
{
printf("%c", space[i].data);
i = space[i].cur;
}
return;
}
总结:
优点
1.在插入和删除操作肘,只需要修改游标
,不需要移动元素,从而改进了在顺序存储结构中的插入和删
除操作需要移动大量元素的缺点
缺点
失去了顺序存储结构随机存取
的特性。