news 2026/4/16 14:01:23

【数据结构-初阶】详解栈和队列(1)---栈

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【数据结构-初阶】详解栈和队列(1)---栈

🎈主页传送门:良木生香

🔥个人专栏:《C语言》 《数据结构-初阶》《程序设计》

🌟人为善,福随未至,祸已远行;人为恶,祸虽未至,福已远离


目录

一、栈的概念

二、栈的实现

1、栈的结构体

2、栈的初始化

3、入栈

4、出栈

5、计算元素个数

三、代码总和:


上期回顾:我们在上一篇文章中已经学完了带头结点循环双向链表,那么顺序表和链表这一部分内容就算是告一段落了,现在我们要学习的是栈和队列这一块知识

一、栈的概念

栈是一种特殊的线性表,它只允许在固定的一端进行插入和删除元素的操作。进行数据插入和删除的一端我们将其称之为栈顶,另一端不变的我们将其称之为栈底。站中的元素遵循后进先出LIFO(Last in fisrt out)的原则.

我们将栈的插入操作叫做进栈/压栈/入栈

将栈的删除操作叫做出栈,出数据也在栈顶

下面是栈的示意图:

了解了栈的基本特征之后,我们应该用什么样的方式来实现栈呢?是用数组还是链表呢?

如果把栈倒下来看,根据后进先出的特性,那么就相当于我们会在栈尾进行操作更多一点,在数组与链表之间,对于尾部数据进行频繁地修改,数组相对而言就更加合适,代价也比较小,所以我们选择用数组来实现栈

二、栈的实现

1、栈的结构体

用数组来实现栈,那么站的结构体里面就少不了数组,下面是结构体代码:

typedef struct Stack { Elemtype* arr; //指向的是赞栈的栈底 int top; //这个其实是当前整个栈里面的元素个数 int length; //当前栈的容量 }Stack;

top可以说一直指向的是栈顶元素的下一个位置,同时top值也代表了当前栈中的元素个数

length代表的是当前栈的总容量,如果top的值达到了length的值,那就要境内扩容操作了

2、栈的初始化

对栈进行初始化其实就是对结构体里面的元素进行初始化。我们让arr指向NULL,将length与top同时置为0,这就完成了栈的初始化:

void Init_Stack(Stack* pStack) { pStack->arr = NULL; pStack->length = pStack -> top = 0; }

3、入栈

入栈就是就相当于在数组的末尾进行操作

既然是入栈,那传入的参数就要有元素x,下面是具体代码:

//入栈操作: void Push_Stack(Stack* pStack,Elemtype x) { //先判断容量是不是足够 if (pStack->top >= pStack->length) { int newlength = pStack->length == 0 ? 4 : 2 * pStack->length; Stack* newbase = realloc(pStack->arr, newlength * sizeof(Elemtype)); if (newbase == NULL) { printf("申请空间失败,扩容失败...\n"); return; } pStack->arr = newbase; pStack->length = newlength; } //pStack->arr[pStack->top++] = x; *(pStack->arr + pStack->top++) = x; }

我们在插入之前,先给栈分配4个单位大小的空间,如果超出了,那就再继续扩容

4、出栈

出栈就更加简单了,先看下图:

为什么我们只是将top向前一定了一位就完成了出栈的操作呢??这是因为,top我们定义它代表的是当前栈顶元素的下一个位置,当top向前移动一位,就说明现在的栈顶元素是3,而不是4了,这样在输出的时候就直接忽略掉4这个元素,在我们想要继续增加元素的时候,4也会被重新覆盖掉,所以这个方案巧妙就巧妙在只用移动top.下面是具体的代码:

//出栈操作 void Pop_Stack(Stack* pStack) { assert(!isEmpty(pStack)); pStack->top--; //只用将top进行--即可将元素减一 }

看吧,出栈是不是很简单呢?

5、计算元素个数

虽然说是计算元素个数,其实根本不用计算,为什么?因为栈中top的值其实就代表了占中元素的总个数,由此可见,top在整个栈里面是不可或缺的,我们只用返回top值即可,代码如下:

//计算栈里的元素个数 int num(Stack* pStack) { assert(!isEmpty(pStack)); return pStack->top; }

三、代码总和:

栈相对于前面我们学习的数据结构要简单很多,其实就是数组的简单操作,下

#define _CRT_SECURE_NO_WARNINGS 520 #include<stdio.h> #include<stdlib.h> #include<assert.h> #include<windows.h> #include<stdbool.h> typedef int Elemtype; typedef struct Stack { Elemtype* arr; //指向的是赞栈的栈底 int top; //这个其实是当前整个栈里面的元素个数 int length; //当前栈的容量 }Stack; //栈的初始化 void Init_Stack(Stack* pStack) { pStack->arr = NULL; pStack->length = pStack -> top = 0; } //栈的销毁 void Destroy_Stack(Stack* pStack) { assert(pStack); if (pStack->arr) { free(pStack->arr); } pStack->arr = NULL; pStack->length = pStack->top = 0; } //判断栈是否为空 bool isEmpty(Stack* pStack) { assert(pStack); return pStack->top == 0; } //入栈操作: void Push_Stack(Stack* pStack,Elemtype x) { //先判断容量是不是足够 if (pStack->top >= pStack->length) { int newlength = pStack->length == 0 ? 4 : 2 * pStack->length; Stack* newbase = realloc(pStack->arr, newlength * sizeof(Elemtype)); if (newbase == NULL) { printf("申请空间失败,扩容失败...\n"); return; } pStack->arr = newbase; pStack->length = newlength; } //pStack->arr[pStack->top++] = x; *(pStack->arr + pStack->top++) = x; } //出栈操作 void Pop_Stack(Stack* pStack) { assert(!isEmpty(pStack)); pStack->top--; //只用将top进行--即可将元素减一 } //取栈顶元素 Elemtype Get_elem(Stack* pStack) { assert(!isEmpty(pStack)); return *(pStack->arr + pStack->top-1); } //计算栈里的元素个数 int num(Stack* pStack) { assert(!isEmpty(pStack)); return pStack->top; } //打印栈 void my_printf(Stack* pStack) { assert(pStack); if (pStack->top == 0) { printf("当前栈里面没有元素...\n"); return; } for (int i = 0; i < pStack -> top; i++) { printf("%d ",*(pStack->arr+i)); } } //打印菜单 void printf_menu() { printf("=========================================\n"); printf("你可以进行以下操作:\n"); printf("1.入栈 2.出栈 3.计算当前元素个数 4.取栈顶元素\n"); printf("=========================================\n"); printf("\n"); } int main() { Stack L; Stack* pStack = &L; Init_Stack(pStack); int choose = 0; do { system("cls"); printf_menu(); printf("当前的栈为:\n"); my_printf(pStack); printf("\n"); printf("请输入你的选择(按-1结束程序):\n"); scanf("%d", &choose); switch (choose) { case 1: { printf("请输入你想输入的元素个数:\n"); int num = 0; Elemtype data = 0; scanf("%d", &num); printf("请输入元素:\n"); for (int i = 0; i < num; i++) { scanf("%d", &data); Push_Stack(pStack, data); } Sleep(1000); printf("正在录入...\n"); Sleep(1000); printf("录入成功!!!\n"); Sleep(2000); break; } case 2: { Pop_Stack(pStack); printf("正在出栈...\n"); Sleep(1000); printf("出栈成功!!!\n"); Sleep(1000); break; } case 3: { int num_elem = num(pStack); printf("正在计算...\n"); Sleep(2000); printf("当前栈的元素个数为: %d", num_elem); Sleep(2000); break; } case 4: { Sleep(1000); printf("当前栈顶元素为: %d", *(pStack->arr + pStack->top - 1)); Sleep(2000); break; } case -1: { printf("正在退出程序...\n"); Sleep(2000); printf("退出成功!!!\n"); Sleep(2000); break; } default: { printf("输入错误,请重新输入...\n"); Sleep(2000); break; } } } while (choose != -1); Destroy_Stack(pStack); pStack = NULL; return 0; }

那么以上就是我对栈相关知识的分享了~~~~感谢大佬们的阅读~~~~

文章是自己写的哈,有啥描述不对的、不恰当的地方,恳请大佬指正,看到后会第一时间修改,感谢您的阅读。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 10:13:22

聊聊我这次 OpenAI interview 的真实感受(以及它为什么这么挑人)

在真正走完这次 OpenAI interview 之前&#xff0c;我一直以为&#xff1a; 只要工程能力够强、背景够硬&#xff0c;至少不会被“早刷”。 结果事实是—— 这是一次从第一轮开始就不断让你暴露短板的面试。 不是难&#xff0c;而是“藏不住”。 一、OpenAI interview 给我的…

作者头像 李华
网站建设 2026/4/16 10:14:47

Copilot的Plan模式到底好在哪?

Copilot的Plan模式到底好在哪&#xff1f; 本文共 1696 字&#xff0c;阅读预计需要 3 分钟。 Hi&#xff0c;你好&#xff0c;我是Carl&#xff0c;一个本科进大厂做了2年AI研发后&#xff0c;裸辞的AI创业者。 GitHub Copilot 在 VS Code 里提供了四种内置 Agent&#xff…

作者头像 李华
网站建设 2026/4/15 12:00:26

脱口秀段子生成:LobeChat玩转中文谐音梗

LobeChat玩转中文谐音梗&#xff1a;当AI讲起脱口秀 在最近一场即兴喜剧工作坊里&#xff0c;有位编剧苦笑着抱怨&#xff1a;“写段子比写代码还难——至少报错时编译器会告诉你哪行出了问题。”可如果有一天&#xff0c;AI不仅能接梗&#xff0c;还能自己造梗呢&#xff1f;比…

作者头像 李华
网站建设 2026/4/16 10:15:10

初步了解DM数据库

1. &#x1f31f; 前言&#xff1a;国产数据库崛起下的 DM8 价值定位 在信创政策落地与数字化转型加速的双重驱动下&#xff0c;国产数据库迎来黄金发展期。达梦数据库&#xff08;DM8&#xff09;作为国内首款通过 ISO/IEC 9126 质量认证的数据库产品&#xff0c;其自主可控&…

作者头像 李华
网站建设 2026/4/16 10:14:19

LobeChat多轮对话状态管理机制研究

LobeChat多轮对话状态管理机制研究 在智能对话系统日益普及的今天&#xff0c;用户早已不满足于“问一句、答一句”的机械交互。无论是撰写技术文档、调试代码&#xff0c;还是规划一次复杂的旅行行程&#xff0c;人们期望AI助手能像真人一样记住上下文、理解意图&#xff0c;并…

作者头像 李华
网站建设 2026/4/16 10:15:24

HTML如何实现大文件分块上传的暂停与继续功能?

大文件传输系统建设方案&#xff08;.NET技术栈版&#xff09; 一、核心需求分析与技术选型 作为项目负责人&#xff0c;针对当前大文件传输需求面临的开源组件不可靠、跨平台兼容性差、授权成本控制三大挑战&#xff0c;提出以下技术方案&#xff1a; 技术栈匹配策略 后端&a…

作者头像 李华