c语言数据结构(5)——栈

欢迎来到博主的专栏——C语言数据结构
博主id:代码小豪

文章目录

    • 栈的顺序存储结构
      • 栈的插入
      • 空栈的初始化
      • 栈的删除
      • 判断空栈
      • 读取栈顶元素数据
    • 实现顺序栈的所有代码
    • 栈的链式存储结构
      • 链式栈的初始化
      • 链式栈的入栈操作
      • 链式栈的出栈操作
    • 实现链式栈的所有代码

栈是一个特殊线性表,其只能在表尾进行数据的插入与删除,进行数据的插入与删除的一端称为栈顶 (TOP)。

我们可以将栈想象成一个酸菜坛子,往坛子中开始放菜的时候,坛中的酸菜是从底部开始增加的。

当坛子放满酸菜后,我们开坛取出酸菜,酸菜会从顶部开始减少。

栈的顺序存储结构

前面提到了,栈是一个特殊的线性表,所以栈的储存形式也可以像线性表一样分为两种,一种为顺序存储结构的栈(顺序栈)。

既然顺序栈是用顺序结构实现的,那么就可以用数组来实现顺序栈。

顺序栈的结构声明如下:

typedef int SDataType;
typedef struct SeqStack
{SDataType val[MAXSIZE];int TOP;
}SeqStack;

栈的插入

从栈顶插入数据的操作被称为入栈(PUSH)
在这里插入图片描述

将数据插入栈顶的位置,然后栈顶的位置往上挪动一位,用于下一次入栈操作。

为空时,栈顶的位置为0.
在这里插入图片描述

还有一种空栈的表示方法,由于数组中第一个元素的下标是0,但是空栈就代表着0下标处没有元素,所以空栈时,栈顶的位置为-1.
在这里插入图片描述
如果用这个方法表示的空栈,在插入数据时应该先让栈顶往上一步,再插入数据。
在这里插入图片描述

void StackPush(SeqStack* stack, SDataType e)
{if (stack->TOP == MAXSIZE){perror("stack overflow\n");return;}stack->val[stack->TOP] = e;stack->TOP++;
}

空栈的初始化

将一个新生成的栈传入函数进行初始化,初始化的方法根据入栈的形式而定(TOP为0或TOP为-1)

以前者为例,空栈的初始化的函数为

void StackInit(SeqStack* stack)
{stack->TOP = 0;
}

栈的删除

从栈顶删除数据的操作称为出栈(POP)
在这里插入图片描述

出栈的方式很简单,我们不用将当前栈顶的数据进行处理,只需要将TOP的位置往下移动一格就行。

要注意当栈为空栈时的特殊情况,当栈为空栈时,出栈的操作会导致TOP位于非法的位置,当下次进行入栈操作时,就会发生数组越位的错误发生。

判断空栈

判断空栈的条件需要按照初始化时,栈顶的位置为准,以前者为例

bool StackEmpty(SeqStack* stack)
{return stack->TOP == 0;
}

如果TOP为0,那么该函数返回值为true。反之为false。

出栈的函数需要调用判断空栈的函数,如下:

void StackPop(SeqStack* stack)
{if (StackEmpty(stack)){perror("stack is empty\n");return;}stack->top--;
}

读取栈顶元素数据

SDataType StackTop(SeqStack* stack)
{return stack->val[stack->top - 1];
}

实现顺序栈的所有代码

typedef int SDataType;
typedef struct SeqStack
{SDataType val[MAXSIZE];int top;
}SeqStack;void ListStackInit(ListStack* stack)
{assert(stack);stack->top = NULL;stack->lenth = 0;
}void ListStackPush(ListStack* stack, LDataType e)
{StackNode* newnode = malloc(sizeof(StackNode));assert(newnode);newnode->val = e;newnode->next = stack->top;stack->top = newnode;stack->lenth++;
}bool ListStackEmpty(ListStack* stack)
{return stack->top == NULL;
}void ListStackPop(ListStack* stack)
{if (!ListStackEmpty(stack)){perror("stack is empty\n");return;}StackNode* del = stack->top;stack->top = stack->top->next;free(del);
}LDataType ListStackTop(ListStack* stack)
{assert(stack);return stack->top->val;
}

栈的链式存储结构

栈既然是线性表,就可以用链表的形式来实现。

栈是从表尾进行插入和删除,链表可以用尾插\尾删的方法实现出栈和入栈(?)。

在这里插入图片描述

在这里插入图片描述
可以发现,使用尾删法是不能实现出栈操作的,因为单链表不能将TOP回到上一个数据的位置。

为了解决这个问题,我们将TOP的位置变为链表头,将入栈和出栈的操作用头插\头删法来实现。

在这里插入图片描述
在这里插入图片描述
链式栈的结构类型如下:

typedef int LDataType;
typedef struct StackNode
{LDataType val;struct StackNode* next;
}StackNode;typedef struct ListStack
{StackNode* top;int lenth;
};

链式栈的初始化

链式栈的初始化如下

void ListStackInit(ListStack* stack)
{assert(stack);stack->top = NULL;stack->lenth = 0;
}

链式栈的入栈操作

链式栈入栈使用头插法。代码如下:

void ListStackPush(ListStack* stack, LDataType e)
{StackNode* newnode = malloc(sizeof(StackNode));assert(newnode);newnode->val = e;newnode->next = stack->top;stack->top = newnode;stack->lenth++;
}

链式栈的出栈操作

考虑到链表空栈无法出栈,所以先定义一个判断空栈的函数

bool ListStackEmpty(ListStack* stack)
{return stack->top == NULL;
}

链式栈出栈使用头删法。代码如下:

void ListStackPop(ListStack* stack)
{if (ListStackEmpty(stack)){perror("stack is empty\n");return;}StackNode* del = stack->top;stack->top = stack->top->next;free(del);
}

实现链式栈的所有代码

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int LDataType;
typedef struct StackNode
{LDataType val;struct StackNode* next;
}StackNode;typedef struct ListStack
{StackNode* top;int lenth;
}ListStack;void ListStackInit(ListStack* stack);
void ListStackPush(ListStack* stack,LDataType e);
void ListStackPop(ListStack* stack);
bool ListStackEmpty(ListStack* stack);
LDataType ListStackTop(ListStack* stack);void ListStackInit(ListStack* stack)
{assert(stack);stack->top = NULL;stack->lenth = 0;
}void ListStackPush(ListStack* stack, LDataType e)
{StackNode* newnode = malloc(sizeof(StackNode));assert(newnode);newnode->val = e;newnode->next = stack->top;stack->top = newnode;stack->lenth++;
}bool ListStackEmpty(ListStack* stack)
{return stack->top == NULL;
}void ListStackPop(ListStack* stack)
{if (ListStackEmpty(stack)){perror("stack is empty\n");return;}StackNode* del = stack->top;stack->top = stack->top->next;free(del);
}LDataType ListStackTop(ListStack* stack)
{assert(stack);return stack->top->val;
}

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

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

相关文章

学习网络编程No.11【传输层协议之UDP】

引言&#xff1a; 北京时间&#xff1a;2023/11/20/9:17&#xff0c;昨天成功更文&#xff0c;上周实现了更文两篇&#xff0c;所以这周再接再厉。当然做题任在继续&#xff0c;而目前做题给我的感觉以套路和技巧偏多&#xff0c;还是那句话很多东西不经历你就是不懂&#xff…

测试人员如何向开发人员准确清晰地描述问题?

测试人员向开发人员准确清晰地描述问题可以采取以下方法&#xff1a; 提供详细的背景和上下文信息&#xff1a;描述问题发生的环境、前提条件和操作步骤&#xff0c;让开发人员能够了解问题出现的场景。明确问题的症状和表现&#xff1a;清楚地说明问题的具体表现&#xff0c;…

【Python】2. 基础语法

常量和表达式 我们可以把 Python 当成一个计算器, 来进行一些算术运算. 注意: print 是一个 Python 内置的 函数, 这个稍后详细介绍. 可以使用 - * / ( ) 等运算符进行算术运算. 先算乘除, 后算加减. 运算符和数字之间, 可以没有空格, 也可以有多个空格. 但是一般习惯上写一…

LDR6328芯片:智能家居时代的小家电充电革新者

在当今的智能家居时代&#xff0c;小家电的供电方式正变得越来越智能化和高效化。 利用PD&#xff08;Power Delivery&#xff09;芯片进行诱骗取电&#xff0c;为后端小家电提供稳定电压的技术&#xff0c;正逐渐成为行业的新宠。在这一领域&#xff0c;LDR6328芯片以其出色的…

Qt下使用modbus-c库实现PLC线圈/保持寄存器的读写

系列文章目录 提示&#xff1a;这里是该系列文章的所有文章的目录 第一章&#xff1a;Qt下使用ModbusTcp通信协议进行PLC线圈/保持寄存器的读写&#xff08;32位有符号数&#xff09; 第二章&#xff1a;Qt下使用modbus-c库实现PLC线圈/保持寄存器的读写 文章目录 系列文章目录…

前端Vue3项目如何打包成Docker镜像运行

将前端Vue3项目打包成Docker镜像并运行包括几个主要步骤&#xff1a;项目打包、编写Dockerfile、构建镜像和运行容器。下面是一个基本的流程&#xff1a; 1. 项目打包 首先&#xff0c;确保你的Vue3项目可以正常运行和打包。在项目根目录下执行以下命令来打包你的Vue3项目&am…

nest.js使用nest-winston日志一

nest-winston文档 nest-winston - npm 参考&#xff1a;nestjs中winston日志模块使用 - 浮的blog - SegmentFault 思否 安装 cnpm install --save nest-winston winstoncnpm install winston-daily-rotate-file 在main.ts中 import { NestFactory } from nestjs/core; im…

【5G 接口协议】GTP-U协议介绍

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

mysql学习

查看glibc版本 ldd --version --mysql启动失败,尝试启动 1 查看错误日志,端口被占用,参数名写错,有不支持的参数 2 通过mysqld启动 mysqld --default-filemy.cnf & 3 mysqld --no-defaults --basedir/user/local/mysql --datadir/data/mysql/3306/data/ --usermysql 4 str…

深入理解 Nginx 的负载均衡与反向代理

深入理解 Nginx 的负载均衡与反向代理 Nginx 是一个高性能的 HTTP 和反向代理服务器&#xff0c;也是一个 IMAP/POP3/SMTP 代理服务器。由于其出色的性能和灵活性&#xff0c;Nginx 已成为现代 web 架构中的重要组成部分&#xff0c;尤其是在处理高并发连接和大规模流量时。在…

找到数组的中间位置-1991-[简单]

力扣 关键点 从题目中总结出公式 sum * 2 nums[i] total从左往右开始尝试&#xff0c;寻找 i 位置满足上面的公式&#xff0c;为什么从左开始&#xff0c;因为题目要求找到最左边的一个用前缀和的概念来解&#xff0c;从左往右尝试i位置的左边所有数之和&#xff0c;右边所有…

基础小白快速入门Python------>模块的作用和意义

模块&#xff0c; 这个词听起来是如此的高大威猛&#xff0c;以至于萌新小白见了瑟瑟发抖&#xff0c;本草履虫见了都直摇头&#xff0c;好像听上去很难的样子&#xff0c;但是但是&#xff0c;年轻人&#xff0c;请听本少年细细讲述&#xff0c;他只是看起来很难&#xff0c;实…

GO-接口

1. 接口 在Go语言中接口&#xff08;interface&#xff09;是一种类型&#xff0c;一种抽象的类型。 interface是一组method的集合&#xff0c;接口做的事情就像是定义一个协议&#xff08;规则&#xff09;&#xff0c;只要一台机器有洗衣服和甩干的功能&#xff0c;我就称它…

【go语言开发】swagger安装和使用

本文主要介绍go-swagger的安装和使用&#xff0c;首先介绍如何安装swagger&#xff0c;测试是否成功&#xff1b;然后列出常用的注释和给出使用例子&#xff1b;最后生成接口文档&#xff0c;并在浏览器上测试 文章目录 安装注释说明常用注释参考例子 文档生成格式化文档生成do…

C++从零开始的打怪升级之路(day39)

这是关于一个普通双非本科大一学生的C的学习记录贴 在此前&#xff0c;我学了一点点C语言还有简单的数据结构&#xff0c;如果有小伙伴想和我一起学习的&#xff0c;可以私信我交流分享学习资料 那么开启正题 今天分享的是关于模板的知识点 1.非类型模板参数 模板参数分为…

大模型生成,Open API调用

大模型是怎么生成结果的 通俗原理 其实&#xff0c;它只是根据上文&#xff0c;猜下一个词&#xff08;的概率&#xff09;…… OpenAI 的接口名就叫【completion】&#xff0c;也证明了其只会【生成】的本质。 下面用程序演示【生成下一个字】。你可以自己修改 prompt 试试…

高并发下的 AtomicReference 性能陷阱

介绍 Java 提供了 AtomicInteger/AtomicLong 在并发编程里经常用到&#xff0c;它们封装了对 int 和 long 的原子操作。 Java 还提供了 AtomicReference&#xff0c;用于对象引用做原子性的管理&#xff0c;比如 get、set、CAS。 一般情况下 AtomicInteger、AtomicLong 的性能…

mac新环境

1、maven 设置阿里云镜像 打开Maven的settings.xml文件。找到<mirrors>标签&#xff0c;如果没有&#xff0c;可以手动添加。在<mirrors>标签内部添加以下内容&#xff1a; <mirror> <id>nexus-aliyun</id> <mirrorOf>*</mirrorO…

【C++】类的转换函数

使用场景 C中当你创建了一个类&#xff0c;你想把这个类对象转换成基本类型的函数。类对象->基本类型对象 原理 如下实例&#xff0c;设计一个分数类&#xff0c;实现分数转换成double 浮点数的转换函数。并在mian函数隐式调用。 #include<iostream> class Fractio…

6. 使用 Spring Boot进行开发(Developing with Spring Boot)

6. 使用 Spring Boot进行开发&#xff08;Developing with Spring Boot&#xff09; 本节详细介绍了如何使用Spring Boot。它涵盖考虑构建系统、自动配置以及如何运行应用程序等主题。我们还介绍一些 Spring Boot 最新做法。虽然 Spring Boot 没有什么特别之处&#xff08;它只…