数据结构(3.3)——栈的链式存储结构

链栈的定义

采用链式存储的栈成为链栈,链栈的优点是便于多个栈共享存储空间和提高其效率,且不存在栈满上溢的情况通常采用单链表实现。

typedef struct Linknode {int data;          // 数据域struct Linknode* next; // 指针域
} LiStack; // 栈类型定义

链栈的初始化

// 初始化链栈的函数
bool InitLiStack(LiStack* top) {top = (LiStack*)malloc(sizeof(LiStack)); // 分配头结点的内存if (top == NULL) {return false; // 分配失败,返回false}else{top->data = 0; // 初始化数据域,这里可根据需要设置top->next = NULL; // 头结点的next指针指向NULLreturn true; // 分配成功,返回true
}

链栈的入栈操作

栈的链式存储操作其实和单链表的头插法插入很相似,我们完全可以使用单链表的头插法插入元素来模拟入栈操作

//进栈操作
bool Push(LiStack* top, int value) {LiStack* newNode = (LiStack*)malloc(sizeof(LiStack));//分配新结点的内存if (newNode == NULL) {return false;//分配失败,返回false}else {newNode->data = value;//设置新结点的数据域newNode->next = top;//新结点的next指针指向当前的栈顶top = newNode;//更新栈顶指针return true;//进栈成功,返回true}
}

链栈的出栈操作

//出栈操作
bool Pop(LiStack* top, int* value) {if (top == NULL) {return false;}else {*value = top->data;//获取栈顶结点的数据LiStack* temp = top;//临时保存栈顶结点top = top->next;//更新栈顶指针free(temp);//释放栈顶结点内存return true;}
}

在栈操作中,释放 temp 而不是 top 是因为 temp 指向的是即将被弹出的栈顶元素,而 top 指向的是新的栈顶元素。以下是详细解释:

  1. 栈的基本概念:栈是一种后进先出(LIFO)的数据结构。在栈中,最后插入的元素是最先被删除的。

  2. 出栈操作:出栈操作涉及从栈顶删除元素。在链式栈中,这意味着需要删除与 top 指针关联的节点。

  3. temp 的作用:在出栈操作中,temp 被用来临时存储指向当前栈顶节点的指针。这样做的目的是,在删除当前栈顶节点后,top 指针可以安全地移动到下一个节点,而不会丢失对当前栈顶节点的引用。

  4. 释放 temp:一旦 top 指针已经更新为指向下一个节点,temp 指向的节点就不再需要了。此时,释放 temp 指向的内存是安全的,因为它已经不再是栈的一部分。

  5. 不释放 toptop 指针在出栈操作后仍然指向新的栈顶节点。如果释放了 top 指向的节点,那么 top 指针将指向一个已经被释放的内存区域,这将导致未定义行为,可能引发程序崩溃。

  6. 内存管理:在链式栈中,每个节点都是动态分配的内存。当一个节点被弹出栈时,必须释放该节点的内存,以避免内存泄漏。

  7. 代码实现:在您的代码中,free(temp) 正确地释放了即将被弹出的栈顶节点的内存。如果 free(top) 被错误地调用,那么 top 指针将指向一个无效的内存区域,这将破坏栈的结构。

总结来说,释放 temp 是因为 temp 指向的是即将被移除的栈顶节点,而 top 指向的是新的栈顶节点,需要保留以维护栈的结构。

读取栈顶

// 读取栈顶元素的值,不移除它
bool Peek(LiStack* top, int* value) {if (top == NULL) {return false; // 栈为空,无法读取栈顶元素}else {*value = top->data; // 将栈顶元素的值赋给value指针指向的变量return true; // 成功读取栈顶元素}

在这个示例中,Peek 函数接受一个指向栈顶节点的指针 top,以及一个指向 int 类型的指针 value,用于存储栈顶元素的值。如果栈不为空,函数将栈顶元素的值赋给 value 指针指向的变量,并返回 true。如果栈为空,则返回 false。 

判空判满

在链式栈中,由于它是动态分配内存的,所以它不会像数组那样有固定的容量限制,也就不会出现“满”的情况。因此,我们只需要实现一个判断链栈是否为空的方法。

bool IsEmpty(LiStack* stack) {return stack->top == NULL; // 如果栈顶指针为NULL,则栈为空
}

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

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

相关文章

常见的块元素、行内元素以及行内块元素,三者有何不同?

在HTML中,元素可以分为块级元素(block-level elements)、行内元素(inline elements)和行内块元素(inline-block elements)。它们之间的主要区别如下: 块级元素(block-le…

【CUDA】 由GPGPU控制核心架构考虑CUDA编程中线程块的分配

GPGPU架构特点 由于典型的GPGPU只有小的流缓存,因此一个存储器和纹理读取请求通常需要经历全局存储器的访问延迟加上互连和缓冲延迟,可能高达数百个时钟周期。与CPU通过巨大的工作集缓存而降低延迟不同,GPU硬件多线程提供了数以千计的并行独…

YOLOv8改进 添加轻量级注意力机制ELAttention

一、ELA论文 论文地址:2403.01123 (arxiv.org) 二、Efficient Local Attention结构 ELA (Efficient Local Attention) 被用于处理自然语言处理任务中的序列数据。它旨在提高传统注意力机制的效率,并减少其计算和存储成本。 在传统的注意力机制中,计算每个输入位置与所有其…

MYSQL 四、mysql进阶 6(索引的创建与设计原则)

一、索引的声明和使用 1.1 索引的分类 MySQL的索引包括普通索引、唯一性索引、全文索引、单列索引、多列索引和空间索引等。 从 功能逻辑 上说,索引主要有 4 种,分别是普通索引、唯一索引、主键索引、全文索引。 按照 物理实现方式 ,索引可…

centos 7系统升级内核(ELRepo仓库)、小版本升级、自编译内核

使用ELRepo仓库 ELRepo是一个第三方仓库,提供了最新的linux内核版本。 安装ELRepo密钥: rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org 安装ELRepo仓库: rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elre…

Spring Boot与GraphQL的集成

Spring Boot与GraphQL的集成 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将探讨如何在Spring Boot应用中集成GraphQL,这是一种强大的API…

Vue2中跨组件共享公共属性的方法、优缺点与实现

一、vuex(最常用) 优缺点 优点:集中管理状态,组件间解耦,易于调试和测试。缺点:学习成本较高,对于小项目可能过于复杂。 适用场景 大型、复杂的单页面应用(SPA)。需要全局…

Apache Seata配置管理原理解析

本文来自 Apache Seata官方文档,欢迎访问官网,查看更多深度文章。 本文来自 Apache Seata官方文档,欢迎访问官网,查看更多深度文章。 Apache Seata配置管理原理解析 说到Seata中的配置管理,大家可能会想到Seata中适配…

Linux系统基础命令行指令——Ubuntu

基础指令 更新指令 sudo apt update sudo apt upgrade 切换超级管理员 su root 切换路径 //相对、绝对 cd 路径回上一级路径 cd ..cd ../.. 退两级路径 查看当前目录 pwd查看指定路径内容 ls //常见搭配 ls -al 创建目录 mkdir 路径 创建文件 touc…

47.HOOK引擎优化支持CALL与JMP位置做HOOK

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 上一个内容:46.修复HOOK对代码造成的破坏 以 46.修复HOOK对代码造成的破坏 它的代码为基础进行修改 优化的是让引擎支持从短跳JMP(E9&…

第三十章 方法大全(Python)

文章目录 一、日期1、time模块 一、日期 1、time模块 import time方法描述time.sleep(secs)程序暂停执行指定的秒数 time.sleep(secs)参数:secs:推迟执行的秒数Delay execution for a given number of seconds. The argument may bea floating point …

美光科技在2024年1γ工艺技术在10纳米级别启动EUV试产

美光科技(Micron)在2024年针对其1γ(1-gamma)工艺技术在10纳米级别启动EUV(极紫外光刻)试产,这标志着存储行业巨头在EUV采用上的重要一步,尽管相比英特尔和台积电等其他半导体制造商…

【PWN · ret2shellcode | sandbox-bypass | 格式化字符串】[2024CISCN · 华东北赛区]pwn1_

一道栈ret2shellcodesandbox(seccomp)格式化字符串的题目 前言 ret2shellcode,已经不是简单的放到栈上、ret这样一个简单的过程。套一层seccomp的沙箱,打ORW又遇到open受限等等,考虑的蛮多。过程中收获最多的可以说是…

Hugging face Transformers(2)—— Pipeline

Hugging Face 是一家在 NLP 和 AI 领域具有重要影响力的科技公司,他们的开源工具和社区建设为NLP研究和开发提供了强大的支持。它们拥有当前最活跃、最受关注、影响力最大的 NLP 社区,最新最强的 NLP 模型大多在这里发布和开源。该社区也提供了丰富的教程…

【系统架构设计师】计算机组成与体系结构 ⑩ ( 磁盘管理 | 磁盘移臂调度算法 | 先来先服务算法 | 最短寻道时间优先 | 扫描算法 | 循环扫描算法 )

文章目录 一、磁盘移臂调度算法1、磁盘移臂调度算法简介2、先来先服务算法3、最短寻道时间优先4、扫描算法5、循环扫描算法 二、最短寻道时间优先算法示例 一、磁盘移臂调度算法 1、磁盘移臂调度算法简介 磁盘 数据块读取 的 性能 主要由 寻道时间旋转延时 决定 ; 旋转延时 …

ROS 2官方文档(基于humble版本)学习笔记(四)

ROS 2官方文档(基于humble版本)学习笔记(四) 2.客户端库使用colcon构建包(package)创建工作空间(workspace)构建工作空间执行测试(tests)导入环境&#xff08…

第十四届蓝桥杯省赛C++B组G题【子串简写】题解(AC)

题目大意 给定字符串 s s s,字符 a , b a, b a,b,问字符串 s s s 中有多少个 a a a 开头 b b b 结尾的子串。 解题思路 20pts 使用二重循环枚举左端点和右端点,判断是否为 a a a 开头 b b b 结尾的字符串,是则答案加一…

一阶滞后滤波法

一阶滞后滤波法 一阶滞后滤波法:取a=0到1,本次滤波结果=(1-a)乘以本次采样值+a乘以上次滤波结果。 优点: 对周期性干扰具有良好的抑制作用;适用于波动频率较高的场合。 缺点: 相位滞后,灵敏度低;滞后程度取决于a值大小;不能消除滤波频率高于采样频率1/2的干扰信号。 …

Stable Diffusion:最全详细图解

Stable Diffusion,作为一种革命性的图像生成模型,自发布以来便因其卓越的生成质量和高效的计算性能而受到广泛关注。不同于以往的生成模型,Stable Diffusion在生成图像的过程中,采用了独特的扩散过程,结合深度学习技术…

精通Perl正则表达式修饰符:提升文本处理能力的艺术

Perl语言以其强大的文本处理能力而闻名,其中正则表达式是其核心特性之一。正则表达式本身非常强大,但Perl提供的修饰符(Modifiers)进一步扩展了正则表达式的灵活性和表达能力。本文将深入探讨Perl中正则表达式修饰符的使用&#x…