当前位置: 首页 > 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.什么是函数 函数就是实现某一特点功能的代码的封装…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

掌握 HTTP 请求:理解 cURL GET 语法

cURL 是一个强大的命令行工具&#xff0c;用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中&#xff0c;cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...

Python竞赛环境搭建全攻略

Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型&#xff08;算法、数据分析、机器学习等&#xff09;不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...

密码学基础——SM4算法

博客主页&#xff1a;christine-rr-CSDN博客 ​​​​专栏主页&#xff1a;密码学 &#x1f4cc; 【今日更新】&#x1f4cc; 对称密码算法——SM4 目录 一、国密SM系列算法概述 二、SM4算法 2.1算法背景 2.2算法特点 2.3 基本部件 2.3.1 S盒 2.3.2 非线性变换 ​编辑…...

[特殊字符] 手撸 Redis 互斥锁那些坑

&#x1f4d6; 手撸 Redis 互斥锁那些坑 最近搞业务遇到高并发下同一个 key 的互斥操作&#xff0c;想实现分布式环境下的互斥锁。于是私下顺手手撸了个基于 Redis 的简单互斥锁&#xff0c;也顺便跟 Redisson 的 RLock 机制对比了下&#xff0c;记录一波&#xff0c;别踩我踩过…...

DeepSeek越强,Kimi越慌?

被DeepSeek吊打的Kimi&#xff0c;还有多少人在用&#xff1f; 去年&#xff0c;月之暗面创始人杨植麟别提有多风光了。90后清华学霸&#xff0c;国产大模型六小虎之一&#xff0c;手握十几亿美金的融资。旗下的AI助手Kimi烧钱如流水&#xff0c;单月光是投流就花费2个亿。 疯…...

字符串哈希+KMP

P10468 兔子与兔子 #include<bits/stdc.h> using namespace std; typedef unsigned long long ull; const int N 1000010; ull a[N], pw[N]; int n; ull gethash(int l, int r){return a[r] - a[l - 1] * pw[r - l 1]; } signed main(){ios::sync_with_stdio(false), …...

【PX4飞控】mavros gps相关话题分析,经纬度海拔获取方法,卫星数锁定状态获取方法

使用 ROS1-Noetic 和 mavros v1.20.1&#xff0c; 携带经纬度海拔的话题主要有三个&#xff1a; /mavros/global_position/raw/fix/mavros/gpsstatus/gps1/raw/mavros/global_position/global 查看 mavros 源码&#xff0c;来分析他们的发布过程。发现前两个话题都对应了同一…...