当前位置: 首页 > news >正文

第 3 章 栈和队列(链栈)

1. 背景说明

链栈是指用单链表实现的栈,其存储结构为链式存储,实现类似于队列的链式实现,不过在插入元素时链栈在头部插入,而

链式队列在尾部插入,本示例中实现为带头结点的链栈,即栈顶元素为栈指针的下一个元素。

2. 示例代码

1) status.h

/* DataStructure 预定义常量和类型头文件 */#ifndef STATUS_H
#define STATUS_H/* 函数结果状态码 */
#define TRUE 					1			/* 返回值为真 */
#define FALSE 					0			/* 返回值为假 */
#define RET_OK 					0			/* 返回值正确 */
#define INFEASIABLE    		   	2			/* 返回值未知 */
#define ERR_MEMORY     		   	3			/* 访问内存错 */
#define ERR_NULL_PTR   			4			/* 空指针错误 */
#define ERR_MEMORY_ALLOCATE		5			/* 内存分配错 */
#define ERR_NULL_STACK			6			/* 栈元素为空 */
#define ERR_PARA				7			/* 函数参数错 */
#define ERR_OPEN_FILE			8			/* 打开文件错 */
#define ERR_NULL_QUEUE			9			/* 队列为空错 */
#define ERR_FULL_QUEUE			10			/* 队列为满错 */
typedef int Status;							/* Status 是函数的类型,其值是函数结果状态代码,如 RET_OK 等 */
typedef int Bollean;						/* Boolean 是布尔类型,其值是 TRUE 或 FALSE */#endif // !STATUS_H

2) linkStack.h

/* 链栈定义头文件 */#ifndef LINKSTACK_H
#define LINKSTACK_H#include "status.h"typedef int SElemType;typedef struct LNode {SElemType data;struct LNode *next;
} *LinkStack;/* 辅助函数,创建一个新的节点 */
LinkStack MakeNewLNode(SElemType e);/* 操作结果:构造一个空栈 */
Status InitStack(LinkStack *S);/* 初始条件:链栈 S 已存在。操作结果:销毁链栈 S */
Status DestroyStack(LinkStack *S);/* 初始条件:链栈 S 已存在。操作结果:将 S 重置为空表 */
Status ClearStack(LinkStack S);/* 初始条件:链栈 S 已存在。操作结果:若 S 为空表,则返回 TRUE,否则返回 FALSE */
Bollean StackEmpty(LinkStack S);/* 初始条件:链栈 S 已存在。操作结果:返回 S 中数据元素个数 */
int StackLength(LinkStack S);/* S 为带头结点的链栈的头指针。当第 1 个元素存在时, 其值赋给 e 并返回 OK,否则返回 ERROR */
Status GetTop(LinkStack S, SElemType *e);/* 在带头结点的链栈 S 中第 1 个位置之前插入元素 e */
Status Push(LinkStack S, SElemType e);/* 在带头结点的链栈 S 中,删除第 1 个元素,并由 e 返回其值 */
Status Pop(LinkStack S, SElemType *e);/* 初始条件:链栈 S 已存在操作结果:依次对 S 的每个数据元素调用函数 vi()。一旦 vi() 失败,则操作失败 */
Status StackTraverse(LinkStack S, void(*vi)(SElemType));#endif // !LINKSTACK_H

3) linkStack.c

/* 链栈实现源文件 */#include "linkStack.h"
#include <stdio.h>
#include <stdlib.h>/* 辅助函数,创建一个新的节点 */
LinkStack MakeNewLNode(SElemType e)
{LinkStack newLNode = (LinkStack)malloc(sizeof(struct LNode));if (!newLNode) {printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_MEMORY_ALLOCATE);return NULL;}newLNode->data = e;newLNode->next = NULL;return newLNode;
}/* 操作结果:构造一个空栈 */
Status InitStack(LinkStack *S)
{*S = (LinkStack)malloc(sizeof(struct LNode));if (!(*S)) {printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_MEMORY_ALLOCATE);return ERR_MEMORY_ALLOCATE;}(*S)->next = NULL;return RET_OK;
}/* 初始条件:链栈 S 已存在。操作结果:销毁链栈 S */
Status DestroyStack(LinkStack *S)
{LinkStack p;while (*S) {p = (*S)->next;free(*S);*S = p;}return RET_OK;
}/* 初始条件:链栈 S 已存在。操作结果:将 S 重置为空表 */
Status ClearStack(LinkStack S)
{LinkStack p = S->next, q;while (p) {q = p->next;free(p);p = q;}S->next = NULL;return RET_OK;
}/* 初始条件:链栈 S 已存在。操作结果:若 S 为空表,则返回 TRUE,否则返回 FALSE */
Bollean StackEmpty(LinkStack S)
{return (S->next == NULL) ? TRUE : FALSE;
}/* 初始条件:链栈 S 已存在。操作结果:返回 S 中数据元素个数 */
int StackLength(LinkStack S)
{int length = 0;LinkStack p = S->next;while (p) {++length;p = p->next;}return length;
}/* S 为带头结点的链栈的头指针。当第 1 个元素存在时, 其值赋给 e 并返回 OK,否则返回 ERROR */
Status GetTop(LinkStack S, SElemType *e)
{if (!S) {printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_NULL_PTR);return ERR_NULL_PTR;}if (!S->next) {printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_NULL_STACK);return ERR_NULL_STACK;}*e = S->next->data;return RET_OK;
}/* 在带头结点的链栈 S 中第 1 个位置之前插入元素 e */
Status Push(LinkStack S, SElemType e)
{if (!S) {printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_NULL_PTR);return ERR_NULL_PTR;}LinkStack newNode = MakeNewLNode(e);if (!newNode) {printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_NULL_PTR);return ERR_NULL_PTR;}newNode->next = S->next;S->next = newNode;return RET_OK;
}/* 在带头结点的链栈 S 中,删除第 1 个元素,并由 e 返回其值 */
Status Pop(LinkStack S, SElemType *e)
{if (!S) {printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_NULL_PTR);return ERR_NULL_PTR;}if (!S->next) {printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_NULL_STACK);return ERR_NULL_STACK;}LinkStack p = S->next;S->next = p->next;*e = p->data;free(p);return RET_OK;
}/* 初始条件:链栈 S 已存在操作结果:依次对 S 的每个数据元素调用函数 vi()。一旦 vi() 失败,则操作失败 */
Status StackTraverse(LinkStack S, void(*vi)(SElemType))
{LinkStack p = S->next;while (p) {vi(p->data);p = p->next;}return RET_OK;
}

4) auxiliary.h

/* 辅助函数头文件 */#ifndef AUXILIARY_H
#define AUXILIARY_H#include "linkStack.h"/* 打印栈元素 */
void Print(SElemType e);#endif // !AUXILIARY_H

5) auxiliary.c

/* 辅助函数实现源文件 */#include "auxiliary.h"
#include <stdio.h>/* 打印栈元素 */
void Print(SElemType e)
{printf("%d ", e);
}

6) main.c

/* 入口程序源文件 */#include "auxiliary.h"
#include "linkStack.h"
#include "status.h"int main(void)
{LinkStack S;Status ret = InitStack(&S);if (ret != RET_OK) {printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ret);return ret;}for (int i = 0; i < 5; ++i) {Push(S, 2 * (i + 1));}printf("The element of the stack from top to bottom is: ");StackTraverse(S, Print);printf("\n");SElemType e;Pop(S, &e);printf("The element of the top of the stack is %d\n", e);printf("The stack is %s\n", StackEmpty(S) ? "empty" : "not empty");ClearStack(S);printf("After clear the stack, the stack is %s\n", StackEmpty(S) ? "empty" : "not empty");ret = DestroyStack(&S);if (ret == RET_OK) {printf("Destroy stack success!\n");}return ret;
}

3. 输出示例

相关文章:

第 3 章 栈和队列(链栈)

1. 背景说明 链栈是指用单链表实现的栈&#xff0c;其存储结构为链式存储&#xff0c;实现类似于队列的链式实现&#xff0c;不过在插入元素时链栈在头部插入&#xff0c;而 链式队列在尾部插入&#xff0c;本示例中实现为带头结点的链栈&#xff0c;即栈顶元素为栈指针的下一…...

嵌入式面试-经典问题

1、c语言内存模型 2、C语言中的变量定义在什么地方 3、C语言代码如何运行的、关于栈的相关 4、指针函数与函数指针的区分 5、Static关键字的作用 6、const作用 7、进程与线程的区别 8、链表与数组的区别 9、#define宏定义与typedef的区别...

ZLMeidaKit在Windows上启动时:计算机中丢失MSVCR110.dll,以及rtmp推流后无法转换为flv视频流解决

场景 ZLMediaKit在Windows上实现Rtmp流媒体服务器以及模拟rtmp推流和http-flv拉流播放&#xff1a; ZLMediaKit在Windows上实现Rtmp流媒体服务器以及模拟rtmp推流和http-flv拉流播放_zlm流媒体服务器_霸道流氓气质的博客-CSDN博客 按照以上教程启动MediaServer.exe时提示&am…...

项目(智慧教室)第二部分,人机交互页面实现,

使用软件&#xff1a; 1.BmCvtST.exe 这是stm32Cubemx工程下的带三方软件。存在STemWin中。 作用&#xff1a; 图片变成.c文件格式。 2.CodeBlock 3.模拟器工程&#xff08;具体请看上一节&#xff09; 一。emWin环境的搭建 1.codeBlock下载 开源免费。 2.使用stm的C…...

【docker】docker的一些常用命令-------从小白到大神之路之学习运维第92天

目录 一、安装docker-ce 1、从阿里云下载docker-cer.epo源 2、下载部分依赖 3、安装docker 二、启用docker 1、启动docker和不启动查看docker version 2、启动服务查看docker version 有什么区别&#xff1f;看到了吗&#xff1f; 3、看看docker启动后的镜像仓库都有什…...

ubuntu18.04.6的安装教程

目录 一、下载并安装virtualbox virtualbox7.0.8版本的安装 二、Ubuntu的下载与安装 ubuntu18.04.6操作系统 下载 安装 一、下载并安装virtualbox VirtualBox是功能强大的x86和AMD64/Intel64虚拟化企业和家庭使用的产品。VirtualBox不仅是面向企业客户的功能极其丰富的高…...

小白的第一个RNN(情感分析模型)

平台&#xff1a;window10&#xff0c;python3.11.4&#xff0c;pycharm 框架&#xff1a;keras 编写日期&#xff1a;20230903 数据集&#xff1a;英语&#xff0c;自编&#xff0c;训练集和测试集分别有4个样本&#xff0c;标签有积极和消极两种 环境搭建 新建文件夹&am…...

华为云 存在部支持迁移的外键解决方法

DRS 检测出源端存在不支持的外键引用操作 MySQL、GaussDB(for MySQL)为源的全量增量或增量迁移、同步场景&#xff0c;以及MySQL、GaussDB(for MySQL)为源灾备场景 表1 源端存在不支持的外键引用操作 预检查项 源端存在不支持的外键引用操作。 描述 同步对象中存在包含CASC…...

C# winform控件和对象双向数据绑定

实现目的&#xff1a; 控件和对象双向数据绑定 实现结果&#xff1a; 1. 对象值 -> 控件值 2. 控件值 -> 对象值 using System; using System.Windows.Forms;namespace ControlDataBind {public partial class MainForm : Form{People people new People();public Mai…...

达梦8 在CentOS 系统下静默安装

确认系统参数 [rootlocalhost ~]# ulimit -a core file size (blocks, -c) unlimited data seg size (kbytes, -d) unlimited【1048576(即 1GB)以上或 unlimited】 scheduling priority (-e) 0 file size (blocks, -f) unlimite…...

flink k8s sink到kafka报错 Failed to get metadata for topics

可能出现的3种报错 -- 报错1 Failed to get metadata for topics [...]. org.apache.kafka.common.errors.TimeoutException: Call-- 报错2 Caused by: org.apache.kafka.common.errors.TimeoutException: Timed out waiting to send the call. Call: fetchMetadata Heartbe…...

利用大模型MoritzLaurer/mDeBERTa-v3-base-xnli-multilingual-nli-2mil7实现零样本分类

概念 1、零样本分类&#xff1a;在没有样本标签的情况下对文本进行分类。 2、nli:(Natural Language Inference),自然语言推理 3、xnli:(Cross-Lingual Natural Language Inference) ,是一种数据集&#xff0c;支持15种语言&#xff0c;数据集包含10个领域&#xff0c;每个领…...

代码随想录二刷day07

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣454. 四数相加 II二、力扣383. 赎金信三、力扣15. 三数之和四、力扣18. 四数之和 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1…...

点云从入门到精通技术详解100篇-点云的泊松曲面重建方法

目录 前言 相关理论 2.1三维点云 2.2体素滤波 2.3隐式曲面重建 泊松曲面重建及改进...

【STM32】学习笔记(串口通信)

串口通信 通信接口硬件电路电平标准USARTUSART框图 通信接口 串口是一种应用十分广泛的通讯接口&#xff0c;串口成本低、容易使用、通信线路简单&#xff0c;可实现两个设备的互相通信 单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信&#…...

【Unity3D赛车游戏优化篇】新【八】汽车实现镜头的流畅跟随,以及不同角度的切换

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…...

webpack5 (四)

react-cli 中配置 开发环境 const path require(path) const EslintWebpackPlugin require(eslint-webpack-plugin) const HtmlWebpackPlugin require(html-webpack-plugin) const ReactRefreshWebpackPlugin require(pmmmwh/react-refresh-webpack-plugin); //封装处理样…...

电脑硬盘数据恢复一般需要收费多少钱

随着电子信息时代的发展&#xff0c;个人和企业对电脑硬盘中存储的数据越发重视。然而&#xff0c;由于各种原因&#xff0c;硬盘数据丢失的情况屡见不鲜。如果您正陷入这样的困境&#xff0c;您可能会好奇恢复失去的数据需要花费多少钱。本文将为您介绍电脑硬盘数据恢复的一般…...

服务运营 | MSOR文章精选:远程医疗服务中的统计与运筹(二)

作者信息&#xff1a;王畅&#xff0c;陈盈鑫 编者按 在上一期中&#xff0c;我们分享了与远程医疗中运营管理问题相关的两篇文章。其一发表在《Stochastic Systems》&#xff0c;旨在使用排队论与流体近似的方法解决远程医疗中资源配置的问题&#xff1b;其二发表在《Managem…...

QT(9.3)定时器,绘制事件

作业&#xff1a; 自定义一个闹钟 pro文件&#xff1a; QT core gui texttospeechgreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c11# The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecat…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

如何更改默认 Crontab 编辑器 ?

在 Linux 领域中&#xff0c;crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用&#xff0c;用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益&#xff0c;允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙

Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...