《大话数据结构》04 静态链表

1. 静态链表

其实C语言真是好东西,它具有的指针能力,使得它可以非常容易地操作内存中的地址和数据,这比其他高级语言更加灵活方便。后来的面向对象语言,如Java、C#等,虽不使用指针,但因为启用了对象引用机制,从某种角度也间接实现了指针的某些作用。但对于一些语言,如Basic、Fortran等早期的编程高级语言,由于没有指针,链表结构按照前面我们的讲法,它就没法实现了。怎么办呢?

有人就想出来用数组来代替指针,来描述单链表。真是不得不佩服他们的智慧,我们来看看他是怎么做到的。

首先我们让数组的元素都是由两个数据域组成,data和cur。也就是说,数组的每个下标都对应一个data和一个cur。数据域data,用来存放数据元素,也就是通常我们要处理的数据;而游标cur相当于单链表中的next指针,存放该元素的后继在数组中的下标。

我们把这种用数组描述的链表叫做静态链表,这种描述方法还有起名叫做游标实现法。

为了我们方便插入数据,我们通常会把数组建立得大一些,以便有一些空闲空间可以便于插入时不至于溢出。

 另外我们对数组第一个和最后一个元素作为特殊元素处理,不存数据。我们通常把未被使用的数组元素称为备用链表。而数组第一个元素,即下标为0的元素的cur就存放备用链表的第一个结点的下标;而数组的最后一个元素的cur则存放第一个有数值的元素的下标,相当于单链表中的头结点作用,当整个链表为空时,则为0。

此时的图示相当于初始化的数组状态,见下面代码:

假设我们已经将数据存入静态链表,比如分别存放着“甲”、“乙”、“丁”、“戊”、“己”、“庚”等数据,则它将处于如下图所示这种状态。

此时“甲”这里就存有下一元素“乙”的游标2,“乙”则存有下一元素“丁”的下标3。而“庚”是最后一个有值元素,所以它的cur设置为0。而最后一个元素的cur则因“甲”是第一有值元素而存有它的下标为1。而第一个元素则因空闲空间的第一个元素下标为7,所以它的cur存有7。

2. 静态链表的插入操作

静态链表中要解决的是:如何用静态模拟动态链表结构的存储空间的分配,需要时申请,无用时释放。

我们前面说过,在动态链表中,结点的申请和释放分别借用malloc()和free()两个函数来实现。在静态链表中,操作的是数组,不存在像动态链表的结点申请和释放问题,所以我们需要自己实现这两个函数,才可以做插入和删除的操作。

为了辨明数组中哪些分量未被使用,解决的办法是将所有未被使用过的及已被删除的分量用游标链成一个备用的链表,每当进行插入时,便可以从备用链表上取得第一个结点作为待插入的新结点。

这段代码有意思,一方面它的作用就是返回一个下标值,这个值就是数组头元素的cur存的第一个空闲的下标。从上面的图示例子来看,其实就是返回7。那么既然下标为7的分量准备要使用了,就得有接替者,所以就把分量7的cur值赋值给头元素,也就是把8给space[0].cur,之后就可以继续分配新的空闲分量,实现类似malloc()函数的作用。 

现在我们如果需要在“乙”和“丁”之间,插入一个值为“丙”的元素,按照以前顺序存储结构的做法,应该要把“丁”、“戊”、“己”、“庚”这些元素都往后移一位。但目前不需要,因为我们有了新的手段。

新元素“丙”,想插队是吧?可以,你先悄悄地在队伍最后一排第7个游标位置待着,我一会就能帮你搞定。我接着找到了“乙”,告诉他,你的cur不是游标为3的“丁”了,这点小钱,意思意思,你把你的下一位的游标改为7就可以了。“乙”叹了口气,收了钱把cur值改了。此时再回到“丙”那里,说你把你的cur改为3。就这样,在绝大多数人都不知道的情况下,整个排队的次序发生了改变(如下图所示)。

实现代码如下,代码左侧数字为行号。

 

■ 当我们执行插入语句时,我们的目的是要在“乙”和“丁”之间插入“丙”。调用代码时,输入i值为3。

■ 第4行让k=MAX_SIZE–1=999。

■ 第7行,j=Malloc_SSL(L)=7。此时下标为0的cur也因为7要被占用而更改备用链表的值为8。■ 第11~12行,for循环l由1到2,执行两次。代码k=L[k].cur; 得到k=L[999].cur=1,再得到k=L[1].cur=2。

■ 第13行,L[j].cur=L[k].cur;因j=7,而k=2得到L[7].cur=L[2].cur=3。这就是刚才我说的让“丙”把它的cur改为3的意思。■ 第14行,L[k].cur=j;意思就是L[2].cur=7。也就是让“乙”得点好处,把它的cur改为指向“丙”的下标7。

就这样,我们实现了在数组中,实现不移动元素,却插入了数据的操作。没理解可能觉得有些复杂,理解了,也就那么回事。

3. 静态链表的删除操作

故事没完,接着,排在第一个的甲突然接到一电话,看着很急,多半不是家里有紧急情况,就是单位有突发状况,反正稍有犹豫之后就急匆匆离开。这意味着第一位空出来了,那么自然刚才那个收了好处的乙就成了第一位——有人走运起来,喝水都长肉。

和前面一样,删除元素时,原来是需要释放结点的函数free()。现在我们也得自己实现它:

有了刚才的基础,这段代码就很容易理解了。前面代码都一样,for循环因为i=1而不操作,j=k[999].cur=1,L[k].cur=L[j].cur也就是L[999].cur=L[1].cur=2。这其实就是告诉计算机现在“甲”已经离开了,“乙”才是第一个元素。Free_SSL(L,j);是什么意思呢?来看代码:

 

意思就是“甲”现在要走,这个位置就空出来了,也就是,未来如果有新人来,最优先考虑这里,所以原来的第一个空位分量,即下标是8的分量,它降级了,把8给“甲”所在下标为1的分量的cur,也就是space[1].cur=space[0].cur=8,而space[0].cur=k=1其实就是让这个删除的位置成为第一个优先空位,把它存入第一个元素的cur中,如下图所示。 

4. 静态链表的其他操作的相关实现

当然,静态链表也有相应的其他操作的相关实现。比如我们代码中的ListLength就是一个,来看代码。

另外一些操作和线性表的基本操作相同,实现上也不复杂,我们在课堂上就不讲解了。

5. 静态链表优缺点

 

总的来说,静态链表其实是为了给没有指针的高级语言设计的一种实现单链表能力的方法。尽管大家不一定会用得上,但这样的思考方式是非常巧妙的,应该理解其思想,以备不时之需。
 

         

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/247.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言进阶课程学习记录-第36课 - 函数与指针分析

C语言进阶课程学习记录-第36课 - 函数与指针分析 函数类型实验-函数指针实验-回调机制小结 本文学习自狄泰软件学院 唐佐林老师的 C语言进阶课程&#xff0c;图片全部来源于课程PPT&#xff0c;仅用于个人学习记录 函数类型 实验-函数指针 #include <stdio.h>typedef in…

PLC工业网关,实现PLC联网

在当今工业自动化领域&#xff0c;PLC&#xff08;可编程逻辑控制器&#xff09;作为控制系统的核心&#xff0c;其稳定性和可靠性至关重要。然而&#xff0c;随着工业互联网和智能制造的快速发展&#xff0c;如何实现PLC的联网通信&#xff0c;提高数据传输效率&#xff0c;成…

Redis教程——数据类型(哈希、集合)

上篇文章我们学习了Redis教程——数据类型&#xff08;字符串、列表&#xff09;&#xff0c;这篇文章学习Redis教程——数据类型&#xff08;哈希表、集合&#xff09; 哈希表Hash 哈希表是一个string类型的field(字段)和value(值)的映射表&#xff0c;hash特别适合用于存储…

C语言进阶课程学习记录-函数指针的阅读

C语言进阶课程学习记录-函数指针的阅读 5个标识符含义解析技巧 本文学习自狄泰软件学院 唐佐林老师的 C语言进阶课程&#xff0c;图片全部来源于课程PPT&#xff0c;仅用于个人学习记录 5个标识符含义解析 int (*p1) (int* , int (*f) ( int* ) );定义了指针p1,指向函数&#…

OpenHarmony实战开发-如何通过分割swiper区域,实现指示器导航点位于swiper下方的效果。

介绍 本示例介绍通过分割swiper区域&#xff0c;实现指示器导航点位于swiper下方的效果。 效果预览图 使用说明 1.加载完成后swiper指示器导航点&#xff0c;位于显示内容下方。 实现思路 1.将swiper区域分割为两块区域&#xff0c;上方为内容区域&#xff0c;下方为空白区…

采用等价类划分法设计测试用例

例题1 请采用等价类划分法设计测试用例。 考虑软件 app, 它有两个输入变量 , 分别是 name 和 age, 其中 ,name 是至多包含 20 个字母字符的非空字符串 ,age 是整数型变量 ,0 ≤ age ≤ 120 。当输入给 name 的字符串的长度超过 20时 ,name 取前 20 个字符作为 name 的值 ; 如果…

【面试经典 150 | 二分查找】搜索旋转排序数组

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;二分查找 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结构等内容进行…

宏集eX700M系列HMI实现港口设备数据上云

前言 随着港口设备信息化技术的快速发展&#xff0c;越来越多的企业想要把现场设备数据上传到云平台&#xff0c;进而实现关键数据的远程监控和分析处理。在此背景下&#xff0c;国内某信息化公司想要将港口设备数据通过MQTT上传到该公司自研IOT平台&#xff0c;实现数据上云&…

java项目的构建工具-Maven

黑马程序员JavaWeb开发教程 文章目录 一、概述1、介绍&#xff08;1&#xff09;介绍&#xff08;2&#xff09;Maven的作用&#xff08;3&#xff09;官网&#xff08;4&#xff09;仓库 2、安装 二、IDEA 集成 Maven1、配置Maven环境2、创建Maven项目&#xff08;1&#xff0…

入门必备:MySQL本地安装(Windows11)

下载安装 社区版下载地址:https://dev.mysql.com/downloads/ 选择合适自己操作系统的版本&#xff1a; 下载完成后是一个.msi文件&#xff0c;双击安装即可&#xff1b; 接下来请看图&#xff1a; 上面的步骤完成后&#xff0c;大概会弹出黑窗口并且有下面的UI界面&#xff…

Simlab python二次开发1-将所有缸套内表面半径加大1mm

Simlab python二次开发1-将所有缸套内表面半径加大1mm 1、打开模型文件2、getBodiesWithSubString&#xff08;&#xff09;从名字得到Bodies3、建Body类Group3.1、定义放入Group中的Bodies3.2、建Group 4、将缸套内表面建组&#xff0c;并扩半径1mm4.1、simlab.getBodiesFromG…

密码学 | 数字签名 + 数字证书

&#x1f951;原文&#xff1a;数字签名和数字证书的原理解读 - 知乎 &#x1f951;声明&#xff1a;后文图中若未明确指明&#xff0c;默认是 Bob 的公钥或私钥。 Step1&#xff1a;Bob 有两把钥匙&#xff0c;一把是公钥&#xff0c;另一把是私钥。 Step2&#xff1a;Bob 把…

基于Springboot+Vue的Java项目-企业客户管理系统开发实战(附演示视频+源码+LW)

大家好&#xff01;我是程序员一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &am…

00_Linux

文章目录 LinuxLinux操作系统的组成Linux的文件系统Linux操作系统中的文件类型Linux操作系统的组织结构 Linux vs WindowsNAT vs 桥接模式 vs 仅主机Linux Shell命令Linux⽂件与⽬录管理相关指令目录文件普通文件文本编辑 用户管理添加用户删除用户用户组管理 文件权限管理权限…

[生活][杂项] 上班党的注意事项

前言 目前是上班已经接近两年了&#xff0c;目前的状态是&#xff0c;一个人租了一个单间在上班。对于这种情况有以下几点需要注意。 钥匙问题&#xff0c;一定不要陷入钥匙丢失的情况&#xff01;一定不要陷入钥匙丢失的情况&#xff01;一定不要陷入钥匙丢失的情况&#xff…

邮箱群组是什么?怎么创建邮箱群组?

在我们群发邮件时&#xff0c;可能会遇到这样的状况&#xff0c;一个个输入邮箱地址效率很低&#xff0c;而且很容易就漏发。而对于一个企业来说&#xff0c;如果出现这样的问题&#xff0c;很有可能会影响公司的业务进展和团队协作。这个时候我们就需要邮箱群组这个功能&#…

聊聊binlog是什么

1. 上一讲思考題解答:redo日志刷盘策略的选择建议 先给大家解释一下上一讲的思考題&#xff0c;我给大家的一个建议&#xff0c;其实对于redo日志的三种刷盘策略&#xff0c;我们通常建议是设置为1 也就是说&#xff0c;提交事务的时候&#xff0c;redo日志必须是刷入磁盘文件…

AWB学习记录

主要参考食鱼者博客&#xff1a;https://blog.csdn.net/wtzhu_13/article/details/119301096&#xff0c;以及相关的论文&#xff0c;感谢食鱼者老师整理分享。 灰度世界和完全反射 灰度世界法和完全反射法分别是基于(Rmean, Gmean, Bmean)和(Rmax, Gmax, Bmax)来进行白平衡校…

多任务学习的显著优势!

多任务学习是一种机器学习技术&#xff0c;它允许模型同时学习多个相关任务。与不进行多任务的整体学习&#xff08;单任务学习&#xff09;相比&#xff0c;多任务学习具有多个显著优势。 首先&#xff0c;多任务学习可以提高学习效率和速度。在并行学习中&#xff0c;多个任…

数组和指针的联系(C语言)

数组和指针是两种不同的数据类型&#xff0c;数组是一种构造类型&#xff0c;用于存储一组相同类型的变量&#xff1b;而指针是一种特殊类型&#xff0c;专门用来存放数据的地址。数组名除了sizeof(数组名)和&数组名表示整个数组外&#xff0c;其他情况下都表示的是首元素的…