导言
前段时间的文章,学习了线性表中的顺序表以及带头结点的单链表以及它们的操作和实现,现在学习另一种链表,叫静态链表。
用数组进行描述的链表叫静态链表。
静态单链表的存储结构
#define MAXSIZE 1000 //链表的最大长度
typedef struct{
ElemType data;
int cur;
}component,SLinkList[MAXSIZE];
1、这种描述方法便于在不设“指针”类型的高级程序设计语言中使用链表结构。
2、数组的一个分量表示一个结点,同时用游标(指示器cur)代替指针指示结点在数组中的相对位置。数组的第零分量可以看成头结点,其指针域指示链表的第一个节点。
3、这种链表结构需要预先分配一个较大的空间,在作线性表的插入和删除操作,不需要移动元素,只需要修改指针(即cur指示器的值)。
静态链表结构
这张表展示了插入数据元素“SHI”和删除数据元素“ZHENG”之后的情况。
静态链表元素定位算法
假设S为SLinkList型变量,则S[0].cur指示表示第一个结点在数组中的位置,若设置S[0].cur,则S[i].data存储线性表的第一个数据元素,且S[i].cur指示第二个结点在数组中的位置。一般情况下,若i个分量表示链表的第K个节点,则S[i].cur指示第k+1个结点的位置。因此在静态链表中实现线性表的操作和动态链表相似,以整型游标i代替动态指针p,i=S[i].cur的操作实际上就是指针后移操作,类似于 p−>next 。
上面结构图修改后(图(b)),可以看出,此线性表的结构为 ZHAO−>QIAN−>SUN−>LI−>SHI−>ZHOU−>WU−>WANG
int LocateElem_SL(SLinkList S, ElemType e) { // 算法2.13
// 在静态单链线性表L中查找第1个值为e的元素。
// 若找到,则返回它在L中的位序,否则返回0。
int i;
i = S[0].cur; // i指示表中第一个结点
while (i && S[i].data != e) i = S[i].cur; // 在表中顺链查找
return i;
} // LocateElem_SL
本节到此为止,值得一说的是静态链表的插入和删除操作的算法和单链表的算法相似。但是所不同的是,malloc和free算法是需要自己自定义。其次要辨明数组中哪些分量没有被使用,这解决的方法便是使用一个备用链表,这个备用链表是由所有未被使用过的以及被删除的分量用游标构成的一个备用链表,每当进行插入便从备用链表上取得第一个结点作为待插入的新结点(即改变第一个结点的值为待插入的值,以及其的cur指针指向,同时改变自己链表其他后续的cur指示的值,同时备用链表的表头指向需要进行改变,使其指向第二个结点,让第二结点成为新的备用链表的第一结点)。反之,删除是从链表中删除下来的结点链接到备用链表上。