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

【数据结构】千字深入浅出讲解栈(附原码 | 超详解)

在这里插入图片描述

🚀write in front🚀
📝个人主页:认真写博客的夏目浅石.
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝
📣系列专栏:C语言实现数据结构
💬总结:希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🖊
✉️如果无聊的话,就来逛逛我的博客栈吧stack-frame.cn

文章目录

  • 前言
  • 一、栈的概念
  • 二、栈的结构
  • 三、栈的实现
    • 3.1 结构设计
    • 3.2 接口总览
    • 3.3 初始化
    • 3.4 销毁
    • 3.5 判断栈是否为空
    • 3.6 入栈
    • 3.7 出栈
    • 3.8 取栈顶元素
    • 3.9 计算栈的大小
  • 四、 完整代码
    • Stack.h
    • Stack.c
    • test.c
  • 总结


前言

这几天看了数据结构的栈这一节,真的收获很大,第一次看没有动手敲代码就是感觉学了和没学一样,今天也是从新又看了一遍,并且边学边敲代码,终于算是非常理解栈这个东西了,今天就把我所学到的知识给大家分享一下


一、栈的概念

是一个特殊的 线性表

只允许在固定的一段进行插入删除元素的操作。进行数据插入和删除操作的一端称为栈顶,不进行操作的一端称为栈底

栈中的元素遵守 后进先出 (LIFO - Last In First Out) 的原则。也就是先进的后出,后进的先出

栈对于数据的管理主要有两种操作:

  1. 压栈:栈的插入操作叫做进栈 / 压栈 / 入栈,从栈顶进行压栈。
  2. 出栈:栈的删除操作叫做 出栈,从栈顶进行出栈。
    在这里插入图片描述

二、栈的结构

栈一般可以使用 数组或链表 实现。让我们分析一下使用这两种方法实现,栈的结构分别是什么样的。

在分析之前,我们要明确的一点是,栈只对 栈顶 的元素进行操作。

那么对于 顺序栈链式栈 ,那个更加好呢?那必定是 顺序栈,因为使用顺序栈的 尾插尾删非常方便, 且 cpu缓存利用率也更高。而且对于顺序栈实现起来相对简单,所以我们接下来就实现 顺序栈 。

三、栈的实现

3.1 结构设计

我们既然是实现 顺序栈,那么它的结构肯定就和 顺序表 差不多:

typedef struct Stack
{STDatatype* a; // 指向动态开辟的数组int capacity; // 栈的容量int top; // 标识 栈顶的下一个位置的下标 或 栈顶的下标
}ST;

这里的 top 我们需要好好理解一下。当top初始值不同时,top可以表示 栈顶的下一个位置的下标栈顶下标

  1. top = 0top 表示栈顶的下一个位置的下标:

在这里插入图片描述
2. 当 top = -1top 表示栈顶的下标:

在这里插入图片描述

top 初始值为 -1,那么需要先 ++top再压栈。否则会越界。当 最后一次压栈时,为先 ++top 再压栈,top 最后的位置就是栈顶的下标处。

3.2 接口总览

void StackInit(ST* ps); // 初始化
void StackDestroy(ST* ps); // 销毁
void StackPush(ST* ps, STDatatype x); // 压栈
void StackPop(ST* ps); // 出栈
STDatatype StackTop(ST* ps); // 取栈顶元素
bool StackEmpty(ST* ps); // 判空
int StackSize(ST* ps); // 计算栈的大小

3.3 初始化

我们实现的是顺序栈,那么就和顺序表一样,需要创建结构体变量,传结构体的地址,进行初始化。

在初始化的时候就给栈开上四个单位的空间,并且将起始容量设定为4。

注意了我们这里设定的 top = 0,那么表示 top 为栈顶的下一个位置的下标。

void StackInit(ST* ps)
{// 结构体一定不为空,所以需要断言assert(ps);ps->a = (STDatatype*)malloc(sizeof(STDatatype) * 4);if (ps->a == NULL){perror("malloc fail");exit(-1);}ps->capacity = 4;ps->top = 0;
}

3.4 销毁

对于栈的销毁,那么我们就只需要释放动态开辟的空间,将指针置空。并将 capacity 和 top 两个变量置 0即可。

void StackDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->capacity = ps->top = 0;
}

3.5 判断栈是否为空

我们起初设定 top = 0,所以判断栈是否为空,那么只需要看 top 是否为0就可以了。如果为0,返回真 ;不为0,返回假。

bool StackEmpty(ST* ps)
{assert(ps);// 如果 ps->top == 0,返回真// 如果 ps->top !=0,返回假return ps->top == 0;
}

3.6 入栈

void StackPush(ST* ps, STDatatype x)
{assert(ps);// 检查容量if (ps->top == ps->capacity){STDatatype* tmp = (STDatatype*)realloc(ps->a, sizeof(STDatatype) * ps->capacity * 2);if (tmp == NULL){perror("realloc fail");exit(-1);}ps->a = tmp;ps->capacity *= 2;}// 插入元素// top 为栈顶的下一个元素// 先插入再 ++ ps->a[ps->top] = x;ps->top++;
}

3.7 出栈

void StackPop(ST* ps)
{assert(ps);// 如果栈空,则不能删除assert(!StackEmpty(ps));ps->top--;
}

3.8 取栈顶元素

STDatatype StackTop(ST* ps)
{assert(ps);assert(!StackEmpty(ps));return ps->a[ps->top - 1];
}

3.9 计算栈的大小

int StackSize(ST* ps)
{assert(ps);return ps->top;
}

四、 完整代码

Stack.h

#pragma once#include <stdbool.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>typedef int STDatatype;typedef struct Stack
{STDatatype* a;int capacity;int top;   // 初始为0,表示栈顶位置下一个位置下标// 初始为-1,表示栈顶位置的下标
}ST;void StackInit(ST* ps);
void StackDestroy(ST* ps);
void StackPush(ST* ps, STDatatype x);
void StackPop(ST* ps);
STDatatype StackTop(ST* ps);
bool StackEmpty(ST* ps);
int StackSize(ST* ps);

Stack.c

#define _CRT_SECURE_NO_WARNINGS 1 #include "Stack.h"// top 为栈顶 初识值为 -1void StackInit(ST* ps)
{// 结构体一定不为空assert(ps);ps->a = (STDatatype*)malloc(sizeof(STDatatype) * 4);if (ps->a == NULL){perror("malloc fail");exit(-1);}ps->capacity = 4;ps->top = -1;
}void StackDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->capacity = ps->top = 0;
}void StackPush(ST* ps, STDatatype x)
{assert(ps);// 检查容量// 此时 top 一开始为 -1,不能表示栈中元素的数目// top + 1 才是正确的if (ps->top + 1 == ps->capacity){STDatatype* tmp = (STDatatype*)realloc(ps->a, sizeof(STDatatype) * ps->capacity * 2);if (tmp == NULL){perror("realloc fail");exit(-1);}ps->a = tmp;ps->capacity *= 2;}// 插入元素// top 为栈顶元素// 先 ++ 再插入ps->a[++ps->top] = x;
}void StackPop(ST* ps)
{assert(ps);// 如果栈空,则不能删除assert(!StackEmpty(ps));ps->top--;
}STDatatype StackTop(ST* ps)
{assert(ps);assert(!StackEmpty(ps));return ps->a[ps->top];
}bool StackEmpty(ST* ps)
{assert(ps);return ps->top == -1;
}int StackSize(ST* ps)
{assert(ps);return ps->top + 1;
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1 #include "Stack.h"void TestST1()
{ST st;StackInit(&st);StackPush(&st, 1);StackPush(&st, 2);StackPush(&st, 3);StackPush(&st, 4);StackPush(&st, 5);StackPop(&st);StackPop(&st);printf("%d\n", StackTop(&st));
}int main()
{TestST1();
}

总结

  今天学习了栈的知识,初次写数据结构的知识,给我的感觉就是,学三遍不如手敲代码一遍来的实在,所以数据结构的学习我将多画图,多敲代码来学习,希望大家吸取经验和我一起学习数据结构,为后面打比赛刷题打下坚实基础。

  我是夏目浅石,希望和你一起学习进步,刷题无数!!!希望各位大佬能一键三连支持一下博主,hhhh~我们下期见喽
在这里插入图片描述
如果无聊的话,就来逛逛我的博客栈吧stack-frame.cn

原创不易,还希望各位大佬支持一下\textcolor{blue}{原创不易,还希望各位大佬支持一下}原创不易,还希望各位大佬支持一下

👍 点赞,你的认可是我创作的动力!\textcolor{9c81c1}{点赞,你的认可是我创作的动力!}点赞,你的认可是我创作的动力!

⭐️ 收藏,你的青睐是我努力的方向!\textcolor{ed7976}{收藏,你的青睐是我努力的方向!}收藏,你的青睐是我努力的方向!

✏️ 评论,你的意见是我进步的财富!\textcolor{98c091}{评论,你的意见是我进步的财富!}评论,你的意见是我进步的财富!

相关文章:

【数据结构】千字深入浅出讲解栈(附原码 | 超详解)

&#x1f680;write in front&#x1f680; &#x1f4dd;个人主页&#xff1a;认真写博客的夏目浅石. &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd; &#x1f4e3;系列专栏&#xff1a;C语言实现数据结构 &#x1f4ac;总结&#xff1a;希望你看完…...

自动驾驶V2X

1 SoC MDM9250 2 设备网络节点 mhi_swip0 rmnet_mhi0 3 网络协议栈log打印控制 include/linux/netdevice.h ethtool -s eth0 msglvl [level] ethtool -s eth0 msglvl 0x6001 4 URLs MHI initial design review https://lore.kernel.org/lkml/001601d52148$bd852840$388f78c0$c…...

零基础自学网络安全/渗透测试有哪些常见误区?

一、网络安全学习的误区 1.不要试图以编程为基础去学习网络安全 不要以编程为基础再开始学习网络安全&#xff0c;一般来说&#xff0c;学习编程不但学习周期长&#xff0c;且过渡到网络安全用到编程的用到的编程的关键点不多。一般人如果想要把编程学好再开始学习网络安全往…...

ConvMixer:Patches Are All You Need

Patches Are All You Need 发表时间&#xff1a;[Submitted on 24 Jan 2022]&#xff1b; 发表期刊/会议&#xff1a;Computer Vision and Pattern Recognition&#xff1b; 论文地址&#xff1a;https://arxiv.org/abs/2201.09792&#xff1b; 代码地址&#xff1a;https:…...

day10—编程题

文章目录1.第一题1.1题目1.2思路1.3解题2.第二题2.1题目2.2涉及的相关知识2.3思路2.4解题1.第一题 1.1题目 描述&#xff1a; 给定一个二维数组board&#xff0c;代表棋盘&#xff0c;其中元素为1的代表是当前玩家的棋子&#xff0c;0表示没有棋子&#xff0c;-1代表是对方玩…...

如何测量锂电池的电量

锂电池在放电时我们有时需要知道电池的实时电量&#xff0c;如电池电量低了我们就需要及时给锂电池充电&#xff0c;避免电池过度放电。我手里的这个就是个单节锂电池电量显示模块&#xff0c;只需要将这个模块接到锂电池的正负极即可显示电量。这个模块的电量分为四档&#xf…...

菜鸟刷题Day6

⭐作者&#xff1a;别动我的饭 ⭐专栏&#xff1a;菜鸟刷题 ⭐标语&#xff1a;悟已往之不谏&#xff0c;知来者之可追 一.链表内指定区间反转&#xff1a;链表内指定区间反转_牛客题霸_牛客网 (nowcoder.com) 描述 将一个节点数为 size 链表 m 位置到 n 位置之间的区间反转…...

DecimalFormat格式化显示数字

DecimalFormat 是 NumberFormat 的一个具体子类&#xff0c;用于格式化十进制数字&#xff0c;可以实现以最快的速度将数字格式化为你需要的样子。 DecimalFormat 类主要靠 # 和 0 两种占位符号来指定数字长度。0 表示如果位数不足则以 0 填充&#xff0c; # 表示只要有可能就…...

cpu中缓存简介

一级缓存是什么&#xff1a; 一级缓存都内置在CPU内部并与CPU同速运行&#xff0c;可以有效的提高CPU的运行效率。一级缓存越大&#xff0c;CPU的运行效率越高&#xff0c;但受到CPU内部结构的限制&#xff0c;一级缓存的容量都很小。 CPU缓存&#xff08;Cache Memory&#xf…...

【数据结构】二叉树的遍历以及基本操作

目录 1.树形结构 1.概念 2.二叉树 2.1概念 2.2 两种特殊的二叉树 2.3二叉树的存储 2.4二叉树的基本操作 1.手动快速创建一棵简单的二叉树 2.二叉树的遍历 (递归) 3.二叉树的层序遍历 4.获取树中节点的个数 5.获取叶子节点的个数 6.获取第K层节点的个数 7.获取二叉…...

若依框架 --- ruoyi 表格的设置

表格 字典值转换 (1) 方式1&#xff1a;使用字典枚举的方式 var isDownload [[${dict.getType(YES_OR_NO)}]];{field : isDownload,title : 是否允许下载,formatter: function(value, row, index) {return $.table.selectDictLabel(isDownload, value);} }, (2) 方式2&…...

“两会”网络安全相关建议提案回顾

作为新一年的政治、经济、社会等发展的“风向标”&#xff0c;今年“两会”在3月13日顺利闭幕。在今年“两会”期间&#xff0c;多位人大代表也纷纷围绕网络安全、数据安全的未来发展做了提案和建议。 01 “两会”网络安全相关建议和提案回顾 建议统筹智能网联汽车数据收集与共…...

一篇文章带你真正了解接口测试(附视频教程+面试真题)

目录 一、什么是接口测试&#xff1f; 二、为什么要做接口测试&#xff1f; 三、如何开展接口测试&#xff1f; 四、接口测试常见面试题 一、什么是接口测试&#xff1f; 所谓接口&#xff0c;是指同一个系统中模块与模块间的数据传递接口、前后端交互、跨系统跨平台跨数据…...

C/C++每日一练(20230325)

目录 1. 搜索插入位置 &#x1f31f; 2. 结合两个字符串 &#x1f31f; 3. 同构字符串 &#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 搜索插入位置 给定一个排序数…...

Linux操作系统ARM指令集与汇编语言程序设计

一、实验目的1.了解并掌握ARM汇编指令集2.应用ARM指令集编写一个程序操控开发板上的LED灯二、实验要求应用ARM汇编指令集编写程序&#xff0c;实现正常状态下开发板上的LED灯不亮&#xff0c;按下一个按键之后开发板上的LED灯进入流水灯模式。三、实验原理四个LED灯的电路如下图…...

计网之HTTP协议和Fiddler的使用

文章目录一. HTTP概述和fidder的使用1. 什么是HTTP2. 抓包工具fidder的使用2.1 注意事项2.2 fidder的使用二. HTTP协议格式1. HTTP请求格式1.1 基本格式1.2 认识URL1.3 方法2. 请求报头关键字段3. HTTP响应格式3.1 基本格式3.2 状态码一. HTTP概述和fidder的使用 1. 什么是HTT…...

sql性能优化:MS-SQL(SQL Server)跟踪日志信息结果列字段说明,MSSQL的列字段说明(column)

sql性能优化&#xff1a;MS-SQL&#xff08;SQL Server&#xff09;跟踪日志信息结果列字段说明&#xff0c;MSSQL的列字段说明&#xff08;column&#xff09; 参考&#xff1a; SQL:BatchCompleted 事件类 | Microsoft Learn SQL 跟踪 | Microsoft Learn sp_trace_setevent (…...

DNS主从复制

#前提准备&#xff1a;关闭SElinux 关闭防火墙 时间同步 #环境说明&#xff1a;Centos7 #ip地址&#xff1a;dns-master&#xff1a;10.0.0.100 dns-slave&#xff1a;10.0.0.103 web&#xff1a;10.0.0.101 主DNS服务配置 1.安装软件包&#xff1a; yum install bind -…...

常见的js加密/js解密方法

常见的js加密/js解密方法 当今互联网世界中&#xff0c;数据安全是至关重要的。为了保护用户的隐私和保密信息&#xff0c;开发人员必须采取适当的安全措施。在前端开发中&#xff0c;加密和解密技术是一种常见的数据安全措施&#xff0c;其中 JavaScript 是最常用的语言之一。…...

6 python函数

函数 在实现某个功能对应的代码的时候&#xff0c;如果将实现功能对应的函数放到函数中&#xff0c;那么下一次再需要这个功能的时候&#xff0c;就可以不用再写这个功能对应的代码&#xff0c;直接调用这个功能对应的函数。 1.什么是函数 函数就是实现某一特点功能的代码的封装…...

7.避免不必要的渲染

目录 1 组件更新机制 2 虚拟DOM配合Diff算法 3 减轻state 4 shouldComponentUpdate() 4.1 基本使用 4.2 使用参数 5 纯组件 5.1 基本使用 5.2 纯组件的比较方法 shallow compere 1 组件更新机制 当父组件重新渲染时&#xff0c;父组件的所有子组件也会重新…...

国产化大趋势下学习linux的必要性

由于国际上的一些国家的制裁和威胁。最近几年国产化大趋势慢慢的兴起&#xff0c;我们国产化硬件的需求越来越大。对国产操作系统的需求也越来越多&#xff0c;那么我们一直用的Windows系统为什么不用了呢&#xff1f;众所周知的原因&#xff0c;不管是最新的Windows11还是正值…...

浅谈虚树

问题引入 你是否遇到过下面这种问题&#xff1a; SDOI2011 消耗战 在一场战争中&#xff0c;战场由 nnn 个岛屿和 n−1n-1n−1 个桥梁组成&#xff0c;保证每两个岛屿间有且仅有一条路径可达。现在&#xff0c;我军已经侦查到敌军的总部在编号为1的岛屿&#xff0c;而且他们已…...

裸机条件下写一个基于时间片轮转的多任务并发程序

目录前言A. 使用RTOSB.裸机多任务并发前言 在学习各种MCU的时候&#xff0c;都是用在main函数里写一个while(1){/* 执行代码 */}&#xff0c;这种方式只能一个函数运行完以后再运行另一个函数。 假设需求控制多个模块&#xff0c;如显示屏幕信息的同时控制电机&#xff0c;还要…...

RK3588 系统定制开关机动画

平台&#xff1a;ITX-3588J, ROC-RK3588S-PC 系统&#xff1a;Android12.0 作者&#xff1a;jpchen & zzz 一. 功能描述 定制自己的开机动画和关机动画 二. 功能实现 1.开启功能 修改device/rockchip/common/BoardConfig.mk文件 BOOT_SHUTDOWN_ANIMATION_RINGINGtrue2.…...

水文-编程命令快查手册

前言 脑子里面记不住一些命令&#xff0c;每次遇到都得查下。我经常在三个实体电脑&#xff0c;windows/uos/ubuntu不同系统上编程。 所以web版本的笔记查看起来方便点。这里报错下。 二级标题 cmake windows在cmake --build的时候&#xff0c;使用–config&#xff0c;指定…...

如何优雅编写测试用例

当你学会了如何设计测试用例之后&#xff0c;接下来便是开始用例的编写。 在设计阶段&#xff0c;更准确的说应该是识别测试点的过程&#xff0c;而编写阶段则是将测试点细化成一条条测试用例的过程&#xff0c;有了比较全的用例场景后&#xff0c;如何让别人更舒服、更方便、…...

[入门必看]数据结构2.3:线性表的链式表示

[入门必看]数据结构2.3&#xff1a;线性表的链式表示第二章 线性表2.3 线性表的链式表示知识总览2.3.1 单链表的定义2.3.2_1 单链表的插入删除2.3.2_2 单链表的查找2.3.2_3 单链表的建立2.3.3 双链表2.3.4 循环链表2.3.5 静态链表2.3.6 顺序表和链表的比较2.3.1 单链表的定义单…...

Golang流媒体实战之二:回源

欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码)&#xff1a;https://github.com/zq2599/blog_demos 本篇概览 今天的实战是流传输过程中的常见功能&#xff1a;回源如下图&#xff0c;lal(源站)和lal(拉流节点)代表两台电脑&#xff0c;上面都部署了lalVLC在…...

webgl——给场景添加光

文章目录前言光照理论介绍光照效果光源类型反射光颜色向场景中添加光向场景中添加环境光和点光源逐片元光照——更加逼真总结前言 在之前的学习中已经将三维物体添加到了场景中&#xff0c;但是并没有在场景中使用光&#xff0c;照可以使模型更具有立体感&#xff0c;本文主要…...

怎么能找到做系统前的收藏网站/营销软文范例大全300

《斩仙》自推出以来&#xff0c;受到了众多玩家给予的帮助和支持。最近我们收到玩家提出合并服务器的建议&#xff0c;为了让玩家得到更好的游戏体验&#xff0c;结识新的朋友&#xff0c;我们正在努力进行服务器合并工作。由于服务器较多&#xff0c;我们每次将优先选择人气相…...

网站策划书包括哪些内容?/国际财经新闻

这篇文章完全参考&#xff1a;原文&#xff1a;https://blog.csdn.net/u012247418/article/details/83684126 原文讲解的特别详细&#xff0c;希望大家都去看原文 发这篇博客的原因完全只是为了方便自己以后查阅。 1. 构建测试模块&#xff1a;hello 1.1 在linux-3.4/driv…...

政府网站什么时候建设的/现在做网络推广都有什么方式

2019独角兽企业重金招聘Python工程师标准>>> 虚拟机设计团队把类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流(即字节码)”这个动作放到Java虚拟机外部去实现&#xff0c;以便让应用程序自己决定如何去获取所需要的类。实现这个动作的代码模块称…...

沈阳盘古网络做网站做的好么/宁波seo网络推广报价

一.什么是协程&#xff1a; 协程是python中另外一种实现多任务的方式&#xff0c;只不过比线程更小&#xff0c;占用的执行资源&#xff08;理解为需要的资源&#xff09;也更少。为啥说他说一个执行单元&#xff1f;因为他自带cpu上下文&#xff0c;这样&#xff0c;在合适的额…...

免费app做logo的网站/关键词有哪些关联词

下载Visual Paradigm最新试用版第三部分 - 用UML序列图指定多方编排在多服务合同中&#xff0c;可以在交互图中显示各方之间的通信和编排。像UML序列图这样的交互图显示了谁调用谁以及何时进行调用。让我们绘制一个序列图来指定纳税服务的编排。单击服务合同纳税服务。单击形状…...

成都旅游网站建设/b2b平台都有哪些网站

转自&#xff1a;http://www.cnblogs.com/mingxuan 六种异常处理的陋习 你觉得自己是一个Java专家吗&#xff1f;是否肯定自己已经全面掌握了Java的异常处理机制&#xff1f;在下面这段代码中&#xff0c;你能够迅速找出异常处理的六个问题吗 1 OutputStreamWriter out ... 2 …...