【数据结构】二、线性表:5.静态链表的定义及其基本操作(定义、初始化、插入、查找、删除、遍历、长度、特点)

文章目录

      • 5.静态链表
        • 5.1定义
        • 5.2初始化
        • 5.3插入
        • 5.4查找
        • 5.5删除
        • 5.6遍历
        • 5.7长度
        • 5.8特点

5.静态链表

静态链表是使用数组来模拟链表结构的一种数据结构,用数组的方式实现的链表

它与传统链表的区别在于,静态链表使用数组保存节点,每个节点包括数据域游标(指向下一个节点的位置)。

单链表与静态链表的区别:

单链表: 各个结点在内存中星罗棋布、散落天涯。

静态链表:分配一整片连续的内存空间, 各个结点集中安置。

静态链表的优点

  • 不需要像动态链表那样频繁地进行内存分配和释放,可以节省内存管理的开销。
  • 可以提前分配一定大小的静态存储空间,避免了动态分配内存的不确定性和运行时开销。
  • 实现简单,不需要使用指针,减少了指针操作的复杂性和内存占用。

静态链表的不足

  • 大小固定不可变,不支持动态扩展和缩小。
  • 需要提前分配一定大小的存储空间,可能造成空间的浪费或不足。
  • 插入和删除操作需要重建链表的链接关系,有一定的时间开销。
  • 不能随机存取,只能从头结点依次向后遍历查找。

适用场景

  • 不支持指针的低级语言
  • 数据元素数量固定不变的场景(如操作系统的文件分配表FAT)
    (FAT王道OS视频p51)

在这里插入图片描述

在静态链表中如果要表示,这个结点是最后一个结点,游标的值可以设为 -1, 表示之后已经没有其他结点了。

5.1定义
#define MaxSize 10   	//静态链表的最大长度
//静态链表结构类型的定义,并且使用typedef进行重命名为SLinkList[MaxSize]
typedef struct Node{ElemType data;    	//存储数据元素int next; 			//下一个元素的数组下标
}SLinkList[MaxSize];struct Node a[MaxSizze];//数组a作为静态链表
//等同于
SLinkList a;

链表定义形式,这样可以使用StackLink来创建静态链表的节点,使用PtrStackLink来创建指向静态链表节点的指针。

typedef struct Stack{Elemtype data;  //数据域int cur;   		//游标
}StackLink,*PtrStackLink;  //例如,可以使用以下方式创建一个静态链表节点:
StackLink node;
node.data = 10;
node.cur = 1;PtrStackLink p;
p = &node;

这段代码创建了一个指向静态链表节点的指针 p,然后将其指向 node。
可以通过 p 来访问和操作这个静态链表节点的成员变量。

例如,可以使用以下方式访问静态链表节点的 data 成员变量:

p->data = 10;
p->cur = 1;

这样就可以通过指针 p 操作静态链表节点的数据和指针。

需要注意的是,如果对指针 p 进行重新赋值,则指向的节点也会相应改变。

5.2初始化
const int MAX_SIZE = 100;	//静态链表的最大容量// 初始化静态链表
void initList(struct Node space){for(int i=0; i<MAX_SIZE-1; i++) {space[i].next = i+1; 	//每个节点的 next 指向下一个节点}space[MAX_SIZE-1].next = 0;	//最后一个节点的 next 设置为0表示链表结束
}
5.3插入

静态链表的节点插入的步骤:

  1. 查找插入位置:

遍历静态链表,找到要插入位置的前一个节点。可以使用一个游标来遍历链表,初始时指向链表的头节点。

  1. 分配新节点:

在静态链表的空闲位置上分配一个新节点,为新节点赋值。

  1. 插入节点:

将新节点的下一个节点指向前一个节点的下一个节点,然后将前一个节点的下一个节点指向新节点的位置。

// 在静态链表的头部插入节点
bool insertNode(int data) {int newNodeIndex = space[0].next;	//获取可用节点的索引(即可用数组空间的下标)if (newNodeIndex == 0) {  			//判断备用链表的第一个结点下标是否为0return false; 					//下标为0,链表已满,插入失败}
// 若备用链表第一个结点空闲,则征用该结点,同时更新备用链表的头结点指向,将此被征用的空闲结点的下一空闲结点填补上来。space[0].next = space[newNodeIndex].next; space[newNodeIndex].data = data; 	//设置插入节点的数据space[newNodeIndex].next = space[1].next; //插入结点的 next 指向原先的头结点space[1].next = newNodeIndex; 		//头节点指向插入节点return true;
}
5.4查找

在静态链表中查找数据可以通过遍历链表的方式来完成。由于静态链表没有指针来直接跳转到下一个节点,所以需要使用游标来遍历链表

以下是一种在静态链表中查找数据的示例算法:

  1. 遍历链表,从链表头部开始,通过头节点的索引获取第一个节点的索引。
  2. 遍历链表中的每个节点,判断节点的数据是否与目标数据相等。
  3. 如果相等,找到了目标数据,返回节点的索引。
  4. 如果不相等,获取当前节点的下一个节点,更新当前节点的索引为下一个节点的索引。
  5. 若遍历完整个链表(即当前节点的索引为-1),仍未找到目标数据,则返回-1表示未找到。
  • 按值查找结点:
// 按值查找节点
int findNodeByValue(int value) {int curr = space[1].next;	//从头节点开始遍历while (curr != 0) {if (space[curr].data == value) {return curr; 		//找到节点,返回索引}curr = space[curr].next;}return 0; 					//没找到节点,返回 0
}

这是一个简单的线性查找算法,时间复杂度为O(n),其中n是链表中节点的数量。

  • 按索引查找结点:
// 按索引查找节点的值
int getNodeValueByIndex(int index) {if (index < 0 || index >= MAX_SIZE) {return -1; 	//索引非法,返回 -1 }return space[index].data;
}
5.5删除

静态链表的节点删除步骤:

  1. 找到要删除结点的前一个结点的位置。
  2. 将被删除结点的下一个结点的下标保存下来。
  3. 修改被删除结点的前一个结点的指针域,使其指向被删除结点的下一个结点。
  4. 将被删除结点的下标加入备用链表。

删除指定数据的节点:

// 删除指定数据的节点
bool deleteNode(int data) {int prev = 1; 				//记录当前节点的前一个节点int curr = space[1].next;	//从头节点开始查找while (curr != 0) {if (space[curr].data == data) {break; 				//找到要删除的节点,跳出循环}prev = curr; 			//未找到,则继续向下遍历curr = space[curr].next;}if (curr == 0) {return false; 			//没有找到要删除的节点,删除失败}space[prev].next = space[curr].next;//前一个节点的 next 指向要删除节点的 nextspace[curr].next = space[0].next; 	//被删除的节点的 next 指向当前可用节点space[0].next = curr; 				//更新可用节点的索引return true;
}

在这里插入图片描述

5.6遍历
// 打印静态链表
void printList() {int curr = space[1].next; // 从头节点开始遍历while (curr != 0) {std::cout << space[curr].data << " ";curr = space[curr].next;}std::cout << std::endl;
}
5.7长度
// 获取静态链表长度
int getListLength() {int count = 0;int curr = space[1].next; // 从头节点开始遍历while (curr != 0) {count++;curr = space[curr].next;}return count;
}
5.8特点

静态链表的优点:

  • 相比于动态链表,静态链表的存储空间是预先分配好的,不需要频繁地进行内存申请和释放,因此在一些内存有限或者对内存分配效率有要求的场景下,静态链表可能更为适用。

  • 静态链表在存储空间上是连续的,可以提高数据访问的效率,尤其是在对元素进行遍历、查找和索引访问等操作时,相对于动态链表具有一定的性能优势。

静态链表的缺点:

  • 静态链表的长度是固定的,无法随意扩展或缩小,一旦达到最大长度,就无法再插入新节点。
  • 静态链表在插入和删除节点时,需要进行额外的操作来维护节点间的连接关系,可能会增加一定的编程复杂性。
  • 静态链表的每个节点需预先分配固定大小的存储空间,可能会造成空间的浪费,特别是在某些节点存储的数据量较小的情况下。

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

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

相关文章

mac系统Idea登录codeium不跳转,报错faild download language server

问题描述 idea通过插件中心安装Codeium以后&#xff0c;登录无法正常跳转到登录页&#xff0c;等待一段时间&#xff0c;右下角图标报错**“faild download language server”** 解决方案 根据上面的报错&#xff0c;是没有成功下载“language_server_macos_x64“&#xff0…

CSAPP-程序的机器级表示

文章目录 概念扫盲思想理解经典好图安全事件 概念扫盲 1.汇编代码使用文本格式&#xff0c;相较于汇编的二进制可读性更好 2.程序内存包括&#xff1a;可执行的机器代码、操作系统需要的信息、管理过程调用和返回的运行时栈、用户分配的内存块 3.链接器为函数调用找到匹配的可…

P9889 [ICPC2018 Qingdao R] Plants vs. Zombies 题解 二分+贪心

[ICPC2018 Qingdao R] Plants vs. Zombies 传送门 题面翻译 给定 n n n 个植物和 m m m 的步数限制&#xff0c;每个植物在位置 1 … n 1\dots n 1…n 上。你初始时在位置 0 0 0&#xff0c;每次可以移动到相邻的位置上。 每次设你走完一步后到达的位置是 i i i&#…

数学建模【模糊综合评价分析】

一、模糊综合评价分析简介 提到模糊综合评价分析&#xff0c;就先得知道模糊数学。1965年美国控制论学家L.A.Zadeh发表的论文“Fuzzy sets”标志着模糊数学的诞生。 模糊数学又称Fuzzy数学&#xff0c;是研究和处理模糊性现象的一种数学理论和方法。模糊性数学发展的主流是在…

大语言模型系列-GPT-3

文章目录 前言一、GTP-3的改进二、GPT-3的表现总结 前言 《Language Models are Few-Shot Learners&#xff0c;2020》 前文提到GPT-2进一步提升了模型的zero shot能力&#xff0c;但是在一些任务中仍可能会“胡说”&#xff0c;GTP-3基于此提出了few shot&#xff0c;即预测…

7-22 试试手气(Python)

我们知道一个骰子有 6 个面&#xff0c;分别刻了 1 到 6 个点。下面给你 6 个骰子的初始状态&#xff0c;即它们朝上一面的点数&#xff0c;让你一把抓起摇出另一套结果。假设你摇骰子的手段特别精妙&#xff0c;每次摇出的结果都满足以下两个条件&#xff1a; 1、每个骰子摇出…

ZYNQ--AXI_DMA使用

文章目录 手册阅读典型连接图SG模式关闭时的寄存器地址SG模式开启时的寄存器地址BD设计PS端设计对于DMA寄存器的控制对DMA进行初始化 手册阅读 典型连接图 SG模式关闭时的寄存器地址 SG模式开启时的寄存器地址 关于各个bit的功能&#xff0c;具体看数据手册。 BD设计 通过PL侧…

sql高级

sql高级 SQL SELECT TOP 子句 SELECT TOP 子句用于规定要返回的记录的数目。 SELECT TOP 子句对于拥有数千条记录的大型表来说&#xff0c;是非常有用的。 **注意:**并非所有的数据库系统都支持 SELECT TOP 语句。 MySQL 支持 LIMIT 语句来选取指定的条数数据&#xff0c; O…

Qt + mqtt对接阿里云平台(一)

一、阿里云平台 官网&#xff1a;点击跳转 二、创建产品与设备 1、“公共实例” 2、“设备管理”->“产品”->“创建产品” 3、“产品名称”->“自定义品类”->"确认" 4、“前往添加” 5、“添加设备” 6、摄入DeviceName和备注名称 7、"前往查…

每周一算法:A*(A Star)算法

八数码难题 题目描述 在 3 3 3\times 3 33 的棋盘上&#xff0c;摆有八个棋子&#xff0c;每个棋子上标有 1 1 1 至 8 8 8 的某一数字。棋盘中留有一个空格&#xff0c;空格用 0 0 0 来表示。空格周围的棋子可以移到空格中。要求解的问题是&#xff1a;给出一种初始布局…

文心一言 VS 讯飞星火 VS chatgpt (210)-- 算法导论16.1 1题

一、根据递归式(16.2)为活动选择问题设计一个动态规划算法。算法应该按前文定义计算最大兼容活动集的大小 c[i,j]并生成最大集本身。假定输入的活动已按公式(16.1)排好序。比较你的算法和GREEDY-ACTIVITY-SELECTOR的运行时间。如何要写代码&#xff0c;请用go语言。 文心一言&…

excel统计分析——裂区设计

参考资料&#xff1a;生物统计学 裂区设计&#xff08;split-plot design&#xff09;是安排多因素试验的一种方法&#xff0c;裂区设计对因素的安排有主次之分&#xff0c;适用于安排对不同因素试验精度要求不一的试验。 裂区设计时&#xff0c;先按第一因素的处理数划分主区&…

独立站营销新纪元:AI与大数据塑造个性化体验的未来

随着全球互联网的深入发展和数字化转型的不断推进&#xff0c;作为品牌建设和市场营销的重要载体&#xff0c;独立站将迎来新的发展机遇。新技术的涌现&#xff0c;特别是人工智能和大数据等技术的广泛应用&#xff0c;为独立站带来了前所未有的机遇与挑战。本文Nox聚星将和大家…

ios xcode 15 PrivacyInfo.xcprivacy 隐私清单

1.需要升级mac os系统到13 兼容 xcode 15.1 2.升级mac os系统到14 兼容 xcode 15.3 3.选择 New File 4.直接搜索 privacy 能看到有个App Privacy 5.右击Add Row 7.直接选 Label Types 8.选中继续添加就能添加你的隐私清单了 苹果官网文档Describing data use in privacy man…

springboot247人事管理系统

人事管理系统的设计与实现 摘 要 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff0c;然而&#xff0c;随着近些年信息技术的迅猛发展&#xff0c;让许多比较老套的信息管理模式进行了更新迭代&#xff0c;问卷信息因为其管理内容繁杂&#xff0c;管理数量繁多导…

Redis基本使用和基础知识整理

Redis是做什么的&#xff1f; Redis是一个开源&#xff0c;内存存储的数据结构服务器&#xff0c;可用作数据库&#xff0c;高速缓存和消息队列。Redis将数据储存在内存当中 内存的特点 易失性&#xff08;在断电之后数据就没有了&#xff09;进行读取数据等IO操作的速度要比…

C语言进阶—表达式求值

隐式类型转换&#xff1a; C 的整型算术运算总是至少以缺省(默认)整型类型的精度来进行的。 为了获得这个精度&#xff0c;表达式中的字符和短整型操作数在使用之前被转换为普通整型&#xff0c;这种转换称为整型提升。 #include <stdio.h>int main() {char c 1;printf(…

Springboot 的几种配置文件形式

方式一&#xff1a;多个yml文件 步骤1&#xff1a;创建多个配置文件 application.yml #主配置文件 application-dev.yml #开发环境的配置 application-prod.yml #生产环境的配置 application-test.yml #测试环境的配置步骤2&#xff1a;applicaiton.yml中指定配置 在a…

代码随想录day13(1)栈与队列:用栈实现队列(leetcode232)

题目要求&#xff1a;使用栈实现push、pop、empty、peek&#xff08;返回队列首部元素&#xff09;。 思路&#xff1a;本题思路比较容易&#xff0c;即用两个栈模拟即可&#xff0c;pop时只需要先判断stackout栈是否为空&#xff0c;如果不空直接弹出&#xff0c;如果空就将s…

组合逻辑电路(一)(加法器)

目录 组合逻辑电路的特点及功能描述 采用SSI的组合逻辑电路的分析与设计 采用SSI的组合逻辑电路的分析 采用SII的组合逻辑电路的设计 例 例 例 常用的MSI组合逻辑电路 半加器 全加器 加法器 串行进位加法器 例 例 超前进位加法器 组合逻辑电路的特点及功能描述 小规模集成…