数据结构(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指针指向NULL
    return 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.mfbz.cn/a/779274.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Tkinter布局助手

免费的功能基本可以满足快速开发布局, https://pytk.net/ iamxcd/tkinter-helper: 为tkinter打造的可视化拖拽布局界面设计小工具 (github.com) 作者也把项目开源了,有兴趣可以玩玩

Java中线程的常用方法(并发编程基础)

Java中线程的常用方法 sleep 调用sleep会让当前线程从Running进入TIMED WAITING状态其它线程可以使用 interrupt 方法打断正在睡眠的线程,这时sleep方法会抛出InterruptedException睡眠结束后的线程未必会立刻得到执行建议用TimeUnit的sleep代替Thread的sleep来获得更好的可读…

如何在PD虚拟机中开启系统的嵌套虚拟化功能?pd虚拟机怎么用 Parallels Desktop 19 for Mac

PD虚拟机是一款可以在Mac电脑中运行Windows系统的应用软件。使用 Parallels Desktop for Mac 体验 macOS 和 Windows 的最优性能,解锁强大性能和无缝交互。 在ParallelsDesktop(PD虚拟机)中如何开启系统的嵌套虚拟化功能?下面我们…

vulhub-activemq(CVE-2015-5254)

Apache ActiveMQ 5.13.0版本之前到5.x版本的安全漏洞,该程序引起的漏洞不限制代理中可以序列化的类。远程攻击者可以制作一个特殊的序列化 Java 消息服务 (JMS) ObjectMessage 对象,利用该漏洞执行任意代码。 Apache ActiveMQ 5.x ~ Apache ActiveMQ 5.1…

【人工智能】-- 智能机器人

个人主页:欢迎来到 Papicatch的博客 课设专栏 :学生成绩管理系统 专业知识专栏: 专业知识 文章目录 🍉引言 🍉机器人介绍 🍈机器人硬件 🍍机械结构 🍍传感器 🍍控…

基于Android Studio电影购票系统

目录 项目介绍 图片展示 运行环境 获取方式 项目介绍 主要实为了方便用户随时随地进行电影购票。在配色方面选择了一些富有电影元素的颜色。主要能够实现的功能与流程为: 1.用户首先需要注册用户名填写密码。 2.用户可以用之前注册的用户名和密码进行登录。 3.登…

键盘异常的检测与解决方案

今天对象用Word写文档,按下Ctrl的时候,页面不停地上下滑动,导致无法正常编辑文本。 重启之后,仍然无法解决,推断是键盘坏了。 但是当按下Fn或其他功能键,焦点移除,页面就不会再抖动了。 现在…

[CP_AUTOSAR]_分层软件架构_内容详解

目录 1、软件分层内容1.1、Microcontroller Abstraction Layer1.2、ECU Abstraction Layer1.2.1、I/O HW Abstraction1.2.2、Communication Hardware Abstraction1.2.3、Memory Hardware Abstraction1.2.4、Onboard Device Abstraction1.2.5、Crypto Hardware Abstraction 1.3、…

Docker安装遇到问题:curl: (7) Failed to connect to download.docker.com port 443: 拒绝连接

问题描述 首先,完全按照Docker官方文档进行安装: Install Docker Engine on Ubuntu | Docker Docs 在第1步:Set up Dockers apt repository,执行如下指令: sudo curl -fsSL https://download.docker.com/linux/ubu…

超赞的8款生活APP推荐!

AI视频生成:小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频https://aitools.jurilu.com/每天都会有几十个应用程序发布,一款用得好的应用程序可以极大地丰富您的生活。对于那些不知道哪个应用程序适合您以及您需要哪个应用程…

将excel表格转换为element table(下)

在‘将excel表格转换为element table(上)’我们把excel 转换后通过数据重构绑定到了element table上,现在要做的就是根据源文件进行行列进行合并操作 先看看最终处理的结果 这里在一步步分析实现步骤。 先分析一下合并的逻辑 大致思路理理如上。 思路有了接下来…

微信小程序的农产品商城-计算机毕业设计源码46732

摘 要 随着社会经济的发展和人们消费观念的升级,农产品电商行业逐渐壮大。但传统的农产品销售模式存在信息不透明、中间环节复杂等问题,而微信小程序作为一种便捷的移动应用平台,为农产品商城的建设提供了新的可能性。通过微信小程序的设计与…

上位机图像处理和嵌入式模块部署(mcu项目1:用户手册)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 一个完整的产品,除了上位机软件、固件、硬件、包装之外,一般还需要一个用户手册。好的用户手册应该能够兼顾到大多数人的认…

开发个人Go-ChatGPT--1 项目介绍

开发个人Go-ChatGPT--1 项目介绍 开发个人Go-ChatGPT--1 项目介绍知识点大纲文章目录项目地址 开发个人Go-ChatGPT–1 项目介绍 本文将以一个使用Ollama部署的ChatGPT为背景,主要还是介绍和学习使用 go-zero 框架,开发个人Go-ChatGPT的服务器后端&#x…

电脑为什么会提示丢失msvcp140.dll?怎么修复msvcp140.dll文件会靠谱点

电脑为什么会提示丢失msvcp140.dll?其实只要你的msvcp140.dll文件一损坏,然而你的电脑程序需要运用到这个msvcp140.dll文件的时候,就回提示你丢失了msvcp140.dll文件!因为没有这个文件,你的很多程序都用不了的。今天我…

Redis基础教程(十三):Redis lua脚本

💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝你生活愉快! 💝&#x1f49…

[240706] 史蒂夫·乔布斯近40年前就预言了苹果智能 | Globalping 用于网络诊断和性能测试的命令行工具

目录 史蒂夫.乔布斯近40年前就预言了苹果智能Globalping 用于网络诊断和性能测试的命令行工具功能1. Ping2. Traceroute3. DNS 查询4. HTTP 请求 使用场景1. 网络性能监测2. 故障排除3. 网站性能优化4. 服务可用性监控 优势1. [全球覆盖](https://www.jsdelivr.com/network)2. …

[Vite]Vite插件生命周期了解

[Vite]Vite插件生命周期了解 Chunk和Bundle的概念 Chunk: 在 Vite 中,chunk 通常指的是应用程序中的一个代码片段,它是通过 Rollup 或其他打包工具在构建过程中生成的。每个 chunk 通常包含应用程序的一部分逻辑,可能是一个路由视…

5个实用的文章生成器,高效输出优质文章

在自媒体时代,优质内容的持续输出是吸引读者、提升影响力的关键。然而,对于许多自媒体创作者来说,频繁的创作难免会遭遇灵感枯竭、创作不出文章的困扰。此时,文章生成器便成为了得力的助手。文章生成器的优势能够快速自动生成高质…

C++怎么解决不支持字符串枚举?

首先,有两种方法:使用命名空间和字符串常量与使用 enum class 和辅助函数。 表格直观展示 特性使用命名空间和字符串常量使用 enum class 和辅助函数类型安全性低 - 编译器无法检查字符串有效性,运行时发现错误高 - 编译期类型检查&#xf…