静态链表详解

前言

这篇文章开始,我们来讲述一下静态链表。

什么是静态链表

静态链表是分配一整片连续的内存空间,各个结点集中安置,而不是像单链表那样,每个结点在内存中分散存储。

image-20220710182045769

如上如的存储方式,优点类似于顺序表,但是在这一整片连续的内存空间中,元素不是按照顺序存储的。而是可以打乱顺序存储,这时候就需要将结点分为两个部分,一个部分存储数据元素,另一个部分存储下一个结点所在的下标(称其为游标),比如:头结点存放的下标(游标)为2,代表在2的位置上是静态链表的第一个真正存放数据的结点。头结点的地址为addr,那么静态链表的第一个真正存放数据的结点地址就为:addr + 8*2(这里假设数据元素和游标的大小都为4B)。

在单链表中如果想要表示表尾结点,会让该结点的尾指针指向NULL。而在静态链表中会将游标设置为-1。

用代码定义一个静态链表

#define MaxSize 10			// 静态链表的最大长度
struct Node{				// 静态链表结构类型的定义
    ElemType data;			// 数据域
    int next;				// 游标
}

我们需要的是一整块连续的空间,所以我们可以用数据的方式声明

void testSLinkList(){
    strcut Node a[MaxSize];		// 数组a作为静态链表
}

image-20220710182837633

书上给出的代码比较少见

#define MaxSize 10
typedef struct{
    ElemType data;
    int next;
}SLinkList[MaxSize];

// 等价于

#define MaxSize 10
struct Node{
    ElemType data;
    int next;
};
typedef struct Node SLinkList[MaxSize];

如果用以上的方式定义结构类型,那么我们的声明就会变成

void testSLinkList(){
    SLinkList a;
}

上述这种方式其实意思就是声明一个静态链表a,并且其最大长度为MaxSize,等价于下面这种写法

void testSLinkList(){
    struct Node a[MaxSize];
}

这种写法其实就类似于前面的LNode *LinkList的区别一样,功能完全相同,只是增加了代码的可读性。

静态链表基本操作的实现

初始化单链表

需要将a[0](头结点)的next(游标)设置为-1,并且将空的未存入数据的位置上将游标设置为-2或者其他值(这在后续的插入中有用)

静态链表的查找

从头结点出发挨个往后遍历结点。所以时间复杂度为O(n)

静态链表的插入

静态链表的插入操作步骤:

  1. 找到一个空的结点,存入数据
    • 这里就涉及到要如何找到空的结点
    • 我们在初始化的时候就已经说过将空闲的结点游标设置为-2或者其他特殊的值,那么我们只需要遍历时通过游标是否为-2或者特殊的值来判断该结点是否为空
  2. 从头结点出发找到位序为i-1的结点
  3. 修改新结点的next为-1
  4. 修改i-1的结点的next(游标)

静态链表的删除

静态链表的删除步骤:

  1. 从头结点出发找到前驱结点
  2. 修改前驱节点的游标
  3. 被删除结点next设置为-2

总结

静态链表在408的考察中并不是很多,并且也很少回去考代码实现,所以这里知识简单的介绍。

静态链表其实就是用数组的方式实现的链表。

现在已经用的很少了,只有早期的不支持指针的低级语言会使用该方法来达到类似单链表一样的效果。

优点

  1. 增、删操作不需要大量移动元素

缺点

  1. 不能随机存取,只能从头结点开始以此往后查找
  2. 容量固定不可变

适用场景

  1. 不支持指针的低级语言
  2. 数据元素数量固定不变的场景(如操作系统的文件分配表FAT)

(等学到《操作系统》中的文件管理的时候可以再回过头来体会静态列表有什么作用)

结束语

已同步更新至个人博客:https://www.hibugs.net/index.php/stlinklist/

本人菜鸟一枚,仅分享学习笔记和经验。若有错误欢迎指出!共同学习、共同进步 😃

如果您觉得我的文章对您有所帮助,希望可以点个赞和关注,支持一下!十分感谢~(若您不想也没关系,只要文章能够对您有所帮助就是我最大的动力!)

下一篇文章传送门:正在更新,敬请期待…

  • 29
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值