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

news2024/12/23 4:51:55

文章目录

      • 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) {  			//判断备用链表的第一个结点下标是否为0
        return 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 指向要删除节点的 next
    space[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.coloradmin.cn/o/1498786.html

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

相关文章

Spark 搭建模式(本地、伪分布、全分布模式)

Spark搭建模式 Standalone模式 环境搭建 1.伪分布式 #1.进入$SPARK_HOME/conf [rootmaster ~] cd $SPARK_HOME/conf#2.拷贝spark-env.sh.template [rootmaster conf] cp spark-env.sh.template spark-env.sh [rootmaster conf] vi spark-env.sh# Options for the daemons u…

window mysql 安装出现的问题

1.安装到最后时&#xff0c;报错&#xff1a;authentication_string doesnt have a default value 解决办法&#xff1a; 1.不要关掉该页面&#xff0c;点击skip。 然后单击 back 回退到如下界面 2.去掉 Enable Strict Mode。 不要勾选 2. 最后一步&#xff1a;Start Servic…

变频器学习

西门子变频器 SINAMICS V20 入门级变频器 SINAMICS G120C

SpringMVC实用技术

1.校验框架 1.表单校验框架入门 表单校验的重要性 数据可以随意输入&#xff0c;导致错误的结果。表单校验保障了数据有效性、安全性 表单校验分类 校验位置&#xff1a; 客户端校验 服务端校验 校验内容与对应方式&#xff1a; 格式校验 客户端&#xff1a;使用Js技术…

Android fragment的使用案例

效果图&#xff1a;两个点击事件&#xff0c;显示不同的fragment布局 默认是如下图&#xff0c;点击页面一也如下图 点击页面二如下图&#xff1a; Android Fragment的生命周期是与其所在的Activity紧密相关的。当一个Fragment被添加到Activity中时&#xff0c;它将经历一系列…

挑战杯 基于深度学习的水果识别 设计 开题 技术

1 前言 Hi&#xff0c;大家好&#xff0c;这里是丹成学长&#xff0c;今天做一个 基于深度学习的水果识别demo 这是一个较为新颖的竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f9ff; 更多资料, 项目分享&#xff1a; https://gitee.com/dancheng-senior/pos…

YOLOv9(2):YOLOv9网络结构

1. 前言 本文仅以官方提供的yolov9.yaml来进行简要讲解。 讲解之前&#xff0c;还是要做一些简单的铺垫。 Slice层不做任何的操作&#xff0c;纯粹是做一个占位层。这样一来&#xff0c;在parse_model时&#xff0c;ch[n]可表示第n层的输出通道。 Detect和DDetect主要区别还…

Django cookie 与 session

Django cookie 与 session Cookie 是存储在客户端计算机上的文本文件&#xff0c;并保留了各种跟踪信息。 识别返回用户包括三个步骤&#xff1a; 服务器脚本向浏览器发送一组 Cookie。例如&#xff1a;姓名、年龄或识别号码等。浏览器将这些信息存储在本地计算机上&#xf…

如何理解Redis中的缓存雪崩,缓存穿透,缓存击穿?

目录 一、缓存雪崩 1.1 解决缓存雪崩问题 二、缓存穿透 2.1 解决缓存穿透 三、缓存击穿 3.1 解决缓存击穿 3.2 如何保证数据一致性问题&#xff1f; 一、缓存雪崩 缓存雪崩是指短时间内&#xff0c;有大量缓存同时过期&#xff0c;导致大量的请求直接查询数据库&#xf…

HTTP协议(请求方式,响应方式,请求行、头、体,状态码)是热点面试题【详解】

目录 1. HTTP简介 1.介绍 2.浏览器抓包 3.特点 2. HTTP请求 1.HTTP请求的格式 2.HTTP请求方式 3.GET方式的请求示例 请求行 请求头 请求体 4.POST方式的请求示例 请求行 请求头 请求体 GET和POST的区别 5.HTTP响应 1.HTTP响应的格式 2 常见响应头 3 响应…

python基础(11)《Allure报告中的组件用法》

使用 官方教程&#xff1a;https://docs.qameta.io/allure 入门 想要看到allure报告&#xff0c;需要做2个步骤&#xff1a; 1、pytest执行时关联allure&#xff1a;pytest命令带上--alluredir 结果存放目录或--alluredir结果存放目录&#xff1b; 2、打开执行报告&#xff…

前端性能优化 | CDN缓存

前言 CDN&#xff08;Content Delivery Network&#xff09;是一种分布式的网络架构&#xff0c;通过在全球各地部署节点服务器来快速传输和分发网络内容。CDN的主要目标是提供快速、可靠的内容传输&#xff0c;以提升用户体验。 本文主要从以下方面讲解CDN 什么是CDNCDN的作…

利用GPT开发应用003:GPT分词和预测

文章目录 一、概率问题二、令牌&#xff08;分词&#xff09;三、预测 一、概率问题 像 GPT 这样的大型语言模型接收一个提示&#xff0c;并返回通常在上下文中有意义的输出。例如&#xff0c;提示可以是“今天天气很好&#xff0c;所以我决定”&#xff08;“The weather is n…

vite项目修改node_modules

问题详情 在使用某个依赖的时候遇到了bug&#xff0c;提交issue后不想一直等待到作者更新版本&#xff0c;所以寻求临时自己解决 问题解决 在node_modules里找到需要修改的依赖&#xff0c;修改想要修改的代码 修改后记得保存 然后在node_modules里找到.vite文件夹&#x…

便捷在线导入:完整Axure元件库集合,让你的设计更高效!

Axure元件库包含基本的工具组件&#xff0c;可以使原型绘制节省大量的重复工作&#xff0c;保持整个设计页面的一致性和标准化&#xff0c;同时显得专业。Axure元件库就像我们日常生活中的门把手、自行车踏板和桌子上的螺丝钉&#xff0c;需要组装才能使用。作为一名成熟的产品…

java集合(泛型数据结构)

1.泛型 1.1泛型概述 泛型的介绍 泛型是JDK5中引入的特性&#xff0c;它提供了编译时类型安全检测机制 泛型的好处 把运行时期的问题提前到了编译期间 避免了强制类型转换 泛型的定义格式 <类型>: 指定一种类型的格式.尖括号里面可以任意书写,一般只写一个字母.例如: …

职工医疗报销管理系统

目录 1 系统目标与范围说明... 0 1.1项目名称... 0 1.2问题说明... 0 1.3项目目标... 0 1.4项目范围... 0 1.5初步想法... 0 1.6可行性研究计划... 0 2 可行性分析报告... 1 2.1系统概述... 1 2.2可行性分析... 2 2.3结论意见... 2 3 项目开发计划... 2 3.1系统…

【笔记】Android Telephony 漫游SPN显示定制(Roaming Alpha Tag)

一、功能名词简介和显示规则 Alpha Tag&#xff1a;运营商名称标识符&#xff0c;也是用于标识运营商的一个名称。客户需求描述常用名词&#xff0c;对开发而言都是SPN/PLMN功能模块的内容&#xff0c;状态栏左上角的运营商名称显示。 SPN相关文章&#xff1a; 【笔记】SPN和…

Java on VS Code 2月更新|创建 Maven 模块支持,项目管理体验优化!

作者&#xff1a;Nick Zhu - Senior Program Manager, Developer Division At Microsoft 排版&#xff1a;Alan Wang 大家好&#xff0c;欢迎来到2024年2月的 Visual Studio Code Java 更新&#xff01;在本篇博客中&#xff0c;我们将分享项目管理体验的改进以及 Maven 多模块…

【MySQL | 第三篇】MySQL索引及两种索引分类方法总结

文章目录 3.MySQL索引及两种索引分类方法3.1索引的概念3.1.1相关定义3.1.2查询例子 3.2索引的底层3.2.1二叉树&#xff08;1&#xff09;满二叉树&#xff08;2&#xff09;完全二叉树&#xff08;3&#xff09;二叉查找树&#xff08;4&#xff09;二叉平衡树&#xff08;AVL&…