逻辑结构上相邻的数据元素,存储在指定的一块内存空间中,数据元素只允许在这块内存空间中随机存放,这样的存储结构生成的链表称为静态链表。
静态链表和动态链表的区别:静态链表限制了数据元素存放的位置范围;动态链表是整个内存空间。
静态链表的构建方法
静态链表使用数组这一数据类型预先申请足够大的内存空间。
由于各数据元素在数组申请的内存空间内随机存放,为了体现逻辑上的相邻,为每一个数据元素配备一个具有指针作用的整形变量,用于记录下一元素在数组中的位置。
在数组申请的存储空间中,各数据元素虽随机存储,每一个元素都记录着下一元素在数组中的位置,通过前一个元素,可以找到下一个元素,构成了一条链表,这条被局限在特定内存空间的链表就是静态链表。
静态链表中结点的构成
静态链表中每个结点既有自己的数据部分,还需要存储下一个结点的位置,所以静态链表的存储实现使用的是结构体数组,包含两部分: 数据域 和 游标(存放的是下一个结点在数组中的位置下标)。
实现代码:
typedef struct
{
int data;//数据域
int cur;//游标
}component;
静态链表的空间重复利用
由于静态链表提前申请了有限的内存空间,在使用的过程中,极有可能会出现申请的内存空间不足,需要使用之前被遗弃的内存空间。
被遗弃的意思是:之前已经使用,但是后期对该结点做了摘除操作,该内存空间中存放的是已经不用的垃圾数据。
所以,在整个过程中,需要自己动手把两者区分开,也就是需要自己实现 malloc 和 free 两个函数的作用。
解决的办法是:提前将所有未被使用的结点链成一个备用链表。需要对链表做插入操作时,从备用链表上摘下一个结点使用;删除链表中的结点时,删除的同时链接到备用链表上,以备下次使用。
备用链表和数据链表
第一步:备用链表:(0,1)(1,2)(2,3)(3,4)(4,5)(5,6)(6,0)
数据链表中还没有数据
第二步:向数据链表中插入一个数据,将备用链表上的(1,2)摘下下,提供给数据元素使用,备用链表的(0,1)游标直接变成2就可以了:
备用链表:(0,2)(2,3)(3,4)(4,5)(5,6)(6,0)
数据链表:(1,0)
第三步:继续向数据链表中插入一个数据,备用链表把(2,3)摘下来,备用链表中的(0,1)直接变成3就可以了:
备用链表:(0,3)(3,4)(4,5)(5,6)(6,0)
数据链表:(1,2)(2,0)
以此类推。以上为插入结点的过程,在删除结点的反方向操作过程中,只需要将被删除结点从数据链表上摘除,并添加到备用链表中即可(也就是只改变相关结点的游标的值)。
创建并初始化链表
建立静态链表 S,存储线性表(a,b,c,d):
创建结构体数组,例如名为 array,存储空间足够大;
先将 array 数组中的分量全部链接到备用链表上;(使用 reserveArr 函数实现)
从备用链表上申请一个分量作为链表 S 的头结点,每次从备用链表上申请分量链接到 S 链表中,依次类推;<br data-filtered=