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

数据结构 | 栈与队列

 🔥Go for it!🔥
📝个人主页:按键难防
📫 如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀

📖系列专栏:数据结构与算法
🔥 如果感觉博主的文章还不错的话,还请 点赞👍🏻收藏⭐️ + 留言📝​支持 一下博主哦

目录

栈:

顺序存储实现栈:

 判断栈是否为空:

入栈操作:

出栈(弹栈)操作:

读取栈顶元素:

汇总:

队列:

 循环队列(数组实现):

 定义方法:

循环队列入队:

循环队列出队:

汇总:

链式存储实现队列:

定义方法

初始化头尾指针:

入队:

出队:

汇总:


栈:

栈(stack)是一个特殊的线性表,是限定仅在一端(通常是表尾)进行插入和删除操作的线性表。又称为后进先出(Last In First Out)的线性表,简称 LIFO 结构。

特点:

后进先出,先进者后出。

顺序存储实现栈:

#define MaxSize 50 //定义栈的长度
typedef int ElemType;//重定义栈中每个元素的类型,便于修改
typedef struct{ElemType data[MaxSize];//数组int top;//始终指向栈顶的一个变量
}SqStack;
SqStack S;

栈顶(Top):线性表允许进行插入删除的那一端。
栈底(Bottom):固定的,不允许进行插入和删除的另一端。
空栈:不含任何元素的空表。

基本操作:

 判断栈是否为空:

void InitStack(SqStack &S)//初始化栈
{S.top = -1;//让栈为空就是初始化栈
}
bool StackEmpty(SqStack &S)//验证是否初始化成功
{if (S.top == -1){return true;}else{return false;}
}

入栈操作:

前置++,既实现先扩容,又解决了元素入栈。

//入栈
bool Push(SqStack &S, ElemType x)
{if (S.top == MaxSize - 1)//数组的大小不能改变,避免访问越界{return false;}S.data[++S.top] = x;{return true;}
}

出栈(弹栈)操作:

后置--,先元素出栈,后减容。

//弹出栈顶元素(出栈)
bool Pop(SqStack &S, ElemType &x)
{if (-1 == S.top)return false;x = S.data[S.top--];//后减减,x=S.data[S.top];S.top=S.top-1;{return true; }
}

读取栈顶元素:

//读取栈顶元素
bool GetTop(SqStack &S, ElemType &x)
{if (-1 == S.top)//说明栈为空{return false;}x = S.data[S.top];{return true;}
}

汇总:

初始化栈,判断栈是否为空,压栈,获取栈顶元素,弹栈。注意 S.top 为-1 时,代表栈为空。

#include <stdio.h>
#include <stdlib.h>
#define MaxSize 50
typedef int ElemType;
typedef struct{ElemType data[MaxSize];//数组int top;
}SqStack;
void InitStack(SqStack &S)
{S.top = -1;//代表栈为空
}
bool StackEmpty(SqStack &S)
{if (S.top == -1){return true;}else{return false;}
}
//入栈
bool Push(SqStack &S, ElemType x)
{if (S.top == MaxSize - 1)//数组的大小不能改变,避免访问越界{return false;}S.data[++S.top] = x;{return true;}
}
//读取栈顶元素
bool GetTop(SqStack &S, ElemType &x)
{if (-1 == S.top)//说明栈为空{return false;}x = S.data[S.top];{return true;}
}
//弹出栈顶元素(出栈)
bool Pop(SqStack &S, ElemType &x)
{if (-1 == S.top)return false;x = S.data[S.top--];//后减减,x=S.data[S.top];S.top=S.top-1;{return true; }
}
//实现栈 可以用数组,也可以用链表,我们这里使用数组
int main()
{SqStack S;//先进后出 FILO LIFObool flag;ElemType m;//用来存放拿出的元素InitStack(S);//初始化flag = StackEmpty(S);//验证是否初始化成功if (flag){printf("栈是空的\n");}Push(S, 3);//入栈元素 3Push(S, 4);//入栈元素 4Push(S, 5);flag = GetTop(S, m);//获取栈顶元素if (flag){printf("获取栈顶元素为 %d\n", m);}flag = Pop(S, m);//弹出栈顶元素(出栈)if (flag){printf("弹出元素为 %d\n", m);}return 0;
}

队列:

队列(Queue)简称队,也是一种操作受限的线性表,只允许在表的一端进行插入,而在表的另一端进行删除。向队列中插入元素称为入队或进队;删除元素称为出队或离队。

特点:

先进先出。

 循环队列(数组实现):

 定义方法:

#define MaxSize 5
typedef int ElemType;
typedef struct{ElemType data[MaxSize];//数组,存储MaxSize-1个元素int front, rear;//队列头 队列尾
}SqQueue;
SqQueue Q;
front和rear都是下标
判断队列为空:front和rear指向同一个单元,且都是0
Q.front==Q.rear
判断队列满:front和rear中间空一个单元
(Q.rear+1)%MaxSize==Q.front
Q.rear+1为容量,如果%MaxSize=0(Q.front),那么队列满

循环队列入队:

bool EnQueue(SqQueue &Q, ElemType x)
{if ((Q.rear + 1) % MaxSize == Q.front) //判断是否队满return false;Q.data[Q.rear] = x;//放入元素Q.rear = (Q.rear + 1) % MaxSize;//改变队尾标记,% MaxSize防止超出容量return true;
}

循环队列出队:

bool DeQueue(SqQueue &Q, ElemType &x)
{if (Q.rear == Q.front)//判断是否队为空return false;x = Q.data[Q.front];//先进先出Q.front = (Q.front + 1) % MaxSize;//改变队头标记,% MaxSize防止超出容量return true;
}

汇总:

#include <stdio.h>
#include <stdlib.h>
#define MaxSize 5
typedef int ElemType;
typedef struct{ElemType data[MaxSize];//数组,存储 MaxSize-1 个元素int front, rear;//队列头 队列尾
}SqQueue;
void InitQueue(SqQueue &Q)
{Q.rear = Q.front = 0;
}
//判空
bool isEmpty(SqQueue &Q)
{if (Q.rear == Q.front)//不需要为零{return true;}else{return false;}
}
//入队
bool EnQueue(SqQueue &Q, ElemType x)
{if ((Q.rear + 1) % MaxSize == Q.front) //判断是否队满{return false;}Q.data[Q.rear] = x;//3 4 5 6Q.rear = (Q.rear + 1) % MaxSize;{return true;}
}
//出队
bool DeQueue(SqQueue &Q, ElemType &x)
{if (Q.rear == Q.front){return false;}x = Q.data[Q.front];//先进先出Q.front = (Q.front + 1) % MaxSize;{return true;}
}
int main()
{SqQueue Q;bool ret;//存储返回值ElemType element;//存储出队元素InitQueue(Q);ret = isEmpty(Q);if (ret){printf("队列为空\n");}else{printf("队列不为空\n");}EnQueue(Q, 3);EnQueue(Q, 4);EnQueue(Q, 5);ret = EnQueue(Q, 6);ret = EnQueue(Q, 7);if (ret){printf("入队成功\n");}else{printf("入队失败\n");}ret = DeQueue(Q, element);if (ret){printf("出队成功,元素值为 %d\n", element);}else{printf("出队失败\n");}ret = DeQueue(Q, element);if (ret){printf("出队成功,元素值为 %d\n", element);}else{printf("出队失败\n");}ret = EnQueue(Q, 8);if (ret){printf("入队成功\n");}else{printf("入队失败\n");}return 0;
}

链式存储实现队列:

定义方法:

typedef int ElemType;
typedef struct LinkNode
{//创建结点ElemType data;struct LinkNode *next;
}LinkNode;
typedef struct
{LinkNode *front, *rear;//结构体,用于存放链表头结点和链表尾结点的指针
}LinkQueue;//先进先出
LinkQueue Q;

相对于原有编写的链表增加了尾指针


初始化头尾指针:

void InitQueue(LinkQueue &Q) //初始化头尾指针
{Q.front = Q.rear = (LinkNode*)malloc(sizeof(LinkNode));//为头结点申请空间//初始化时头尾指针都指向这一头结点Q.front->next = NULL;//头结点的next指针为 NULL
}
bool IsEmpty(LinkQueue Q)
{if (Q.front == Q.rear)return true;elsereturn false;
}

入队:

用链表的尾插法进行入队

44d56d1b9ad84b564a33cc8a502ae699.jpeg 

//入队,尾部插入法
void EnQueue(LinkQueue &Q, ElemType x)
{LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));//为入队的元素申请空间s->data = x; s->next = NULL;//新申请的结点作为最后一个结点Q.rear->next = s;//先让前一结点(Q.rear)的指针域指向新插入的结点Q.rear = s;//然后再让Q.rear变为指向尾部的那个结点
}

出队:

头部删除法,删除某一节点

//出队 
bool DeQueue(LinkQueue &Q, ElemType &x)
{if (Q.front == Q.rear) {return false;//队列为空}LinkNode *p = Q.front->next;//front始终指向头结点,但头结点什么都没存,所以头结点的下一个节点才有数据x = p->data;Q.front->next = p->next;//断链,保留第一个结点的指针域,让头节点指向第二个结点if (Q.rear == p)//如果这个队列没有第二个结点,也就是p->next为NULLQ.rear = Q.front;//那直接让队列置为空free(p);//销毁动态内存return true;
}

汇总:

#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct LinkNode{ElemType data;struct LinkNode *next;
}LinkNode;
typedef struct
{LinkNode *front, *rear;//结构体,用于存放链表头和链表尾的指针
}LinkQueue;//先进先出
void InitQueue(LinkQueue &Q) //初始化头尾指针
{Q.front = Q.rear = (LinkNode*)malloc(sizeof(LinkNode));//为头结点申请空间//头尾指针都指向这一头结点Q.front->next = NULL;//头结点的next指针为 NULL
}
bool IsEmpty(LinkQueue Q)
{if (Q.front == Q.rear)return true;elsereturn false;
}
//入队,尾部插入法
void EnQueue(LinkQueue &Q, ElemType x)
{LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));//为入队的元素申请空间s->data = x; s->next = NULL;Q.rear->next = s;//rear 始终指向尾部Q.rear = s;
}
//出队 头部删除法
bool DeQueue(LinkQueue &Q, ElemType &x)
{if (Q.front == Q.rear) return false;//队列为空LinkNode *p = Q.front->next;//头结点什么都没存,所以头结点的下一个节点才有数据x = p->data;Q.front->next = p->next;//断链if (Q.rear == p)//删除的是最后一个元素Q.rear = Q.front;//队列置为空free(p);return true;
}
int main()
{LinkQueue Q;bool ret;ElemType element;//存储出队元素InitQueue(Q);//初始化队列EnQueue(Q, 3);EnQueue(Q, 4);EnQueue(Q, 5);EnQueue(Q, 6);EnQueue(Q, 7);ret = DeQueue(Q, element);if (ret){printf("出队成功,元素值为 %d\n", element);}else{printf("出队失败\n");}return 0;
}

相关文章:

数据结构 | 栈与队列

&#x1f525;Go for it!&#x1f525; &#x1f4dd;个人主页&#xff1a;按键难防 &#x1f4eb; 如果文章知识点有错误的地方&#xff0c;请指正&#xff01;和大家一起学习&#xff0c;一起进步&#x1f440; &#x1f4d6;系列专栏&#xff1a;数据结构与算法 &#x1f52…...

Redux 源码分析

Redux 目录结构 redux ├─ .babelrc.js ├─ .editorconfig ├─ .gitignore …...

第五十二章 BFS进阶(二)——双向广搜

第五十二章 BFS进阶&#xff08;二&#xff09;——双向广搜一、双向广搜1、优越之处2、实现逻辑3、复杂度分析二、例题1、问题2、分析3、代码一、双向广搜 1、优越之处 双向广搜是指我们从终点和起点同时开始搜索&#xff0c;当二者到达同一个中间状态的时候&#xff0c;即相…...

业务建模题

一. 单选题&#xff1a;1.在活动图中负责在一个活动节点执行完毕后切换到另一个节点的元素是( A)。A.控制流 B.对象流 C.判断节点 D.扩展区城2.以下说法错误的是(C)。A.活动图中的开始标记一般只有一一个,而终止标记可能有多个B.判断节点的出口条件必须保证不互相重复,并且不缺…...

电子秤专用模拟数字(AD)转换器芯片HX711介绍

HX711简介HX711是一款专为高精度电子秤而设计的24 位A/D 转换器芯片。与同类型其它芯片相比&#xff0c;该芯片集成了包括稳压电源、片内时钟振荡器等其它同类型芯片所需要的外围电路&#xff0c;具有集成度高、响应速度快、抗干扰性强等优点。降低了电子秤的整机成本&#xff…...

微服务 RocketMQ-延时消息 消息过滤 管控台搜索问题

~~微服务 RocketMQ-延时消息 消息过滤 管控台搜索问题~~ RocketMQ-延时消息实现延时消息RocketMQ-消息过滤Tag标签过滤SQL标签过滤管控台搜索问题RocketMQ-延时消息 给消息设置延时时间&#xff0c;到一定时间&#xff0c;消费者才能消费的到&#xff0c;中间件内部通过每秒钟扫…...

js发送邮件(node.js)

以前看别人博客留言或者评论文章时必须填写邮箱信息&#xff0c;感觉甚是麻烦。 后来才知道是为了在博主回复后让访客收到邮件&#xff0c;用心良苦。 于是我也在新增留言和文章评论的接口里&#xff0c;新增了给自己发送邮件提醒的功能。 我用的QQ邮箱&#xff0c;具体如下…...

English Learning - Day58 一周高频问题汇总 2023.2.12 周日

English Learning - Day58 一周高频问题汇总 2023.2.12 周日这周主要内容继续说说状语从句结果状语从句这周主要内容 DAY58【周日总结】 一周高频问题汇总 &#xff08;打卡作业详见 Day59&#xff09; 一近期主要讲了 一 01.主动脉修饰 以下是最常问到的知识点拓展&#xff…...

【微电网】基于风光储能和需求响应的微电网日前经济调度(Python代码实现)

目录 1 概述 2 知识点及数学模型 3 算例实现 3.1算例介绍 3.2风光参与的模型求解 3.3 风光和储能参与的模型求解 3.5 风光储能和需求响应都参与模型求解 3.6 结果分析对比 4 Python代码及算例数据 1 概述 近年来&#xff0c;微电网、清洁能源等已成为全球关注的热点…...

四种方式的MySQL安装

mysql安装常见的方法有四种序号 安装方式 说明1 yum\rpm简单、快速&#xff0c;不能定制参数2二进制 解压&#xff0c;简单配置就可使用 免安装 mysql-a.b.c-linux2.x-x86_64.tar.gz3源码编译 可以定制参数&#xff0c;安装时间长 mysql-a.b.c.tar.gz4源码制成rpm包 把源码制…...

软考高级信息系统项目管理师系列之九:项目范围管理

软考高级信息系统项目管理师系列之九:项目范围管理 一、范围管理输入、输出、工具和技术表二、范围管理概述三、规划范围管理四、收集需求1.收集需求:2.需求分类3.收集需求的工具与技术4.收集需求过程主要输出5.需求文件内容6.需求管理7.可跟踪性8.双向可跟踪性9.需求跟踪矩阵…...

【项目精选】javaEE健康管理系统(论文+开题报告+答辩PPT+源代码+数据库+讲解视频)

点击下载源码 javaEE健康管理系统主要功能包括&#xff1a;教师登录退出、教师饮食管理、教师健康日志、体检管理等等。本系统结构如下&#xff1a; &#xff08;1&#xff09;用户模块&#xff1a; 实现登录功能 实现用户登录的退出 实现用户注册 &#xff08;2&#xff09;教…...

ctfshow nodejs

web 334 大小写转换特殊字符绕过。 “ı”.toUpperCase() ‘I’&#xff0c;“ſ”.toUpperCase() ‘S’。 “K”.toLowerCase() ‘k’. payload: CTFſHOW 123456web 335 通过源码可知 eval(xxx)&#xff0c;eval 中可以执行 js 代码&#xff0c;那么我们可以依此执行系…...

无线传感器原理及方法|重点理论知识|2021年19级|期末考试

Min-Max定位 【P63】 最小最大法的基本思想是依据未知节点到各锚节点的距离测量值及锚节点的坐标构造若干个边界框,即以参考节点为圆心,未知节点到该锚节点的距离测量值为半径所构成圆的外接矩形,计算外接矩形的质心为未知节点的估计坐标。 多边定位法的浮点运算量大,计算代…...

带你写出符合 Promise/A+ 规范 Promise 的源码

Promise是前端面试中的高频问题&#xff0c;如果你能根据PromiseA的规范&#xff0c;写出符合规范的源码&#xff0c;那么我想&#xff0c;对于面试中的Promise相关的问题&#xff0c;都能够给出比较完美的答案。 我的建议是&#xff0c;对照规范多写几次实现&#xff0c;也许…...

回流与重绘

触发回流与重绘条件&#x1f449;回流当渲染树中部分或者全部元素的尺寸、结构或者属性发生变化时&#xff0c;浏览器会重新渲染部分或者全部文档的过程就称为 回流。引起回流原因1.页面的首次渲染2.浏览器的窗口大小发生变化3.元素的内容发生变化4.元素的尺寸或者位置发生变化…...

openpyxl表格的简单实用

示例:创建简单的电子表格和条形图 在这个例子中,我们将从头开始创建一个工作表并添加一些数据,然后绘制它。我们还将探索一些有限的单元格样式和格式。 我们将在工作表上输入的数据如下: 首先,让我们加载 openpyxl 并创建一个新工作簿。并获取活动表。我们还将输入我们…...

【寒假day4】leetcode刷题

&#x1f308;一、选择题❤1.下列哪一个是析构函数的特征&#xff08; &#xff09;。A: 析构函数定义只能在类体内 B: 一个类中只能定义一个析构函数 C: 析构函数名与类名相同 D: 析构函数可以有一个或多个参数答案&#xff1a;B答案解析&#xff1a;析构函数是构造函…...

【竞赛题】6355. 统计公平数对的数目

题目&#xff1a; 给你一个下标从 0 开始、长度为 n 的整数数组 nums &#xff0c;和两个整数 lower 和 upper &#xff0c;返回 公平数对的数目 。 如果 (i, j) 数对满足以下情况&#xff0c;则认为它是一个 公平数对 &#xff1a; 0 < i < j < n&#xff0c;且 l…...

Redis集群搭建(主从、哨兵、分片)

1.单机安装Redis 首先需要安装Redis所需要的依赖&#xff1a; yum install -y gcc tcl然后将课前资料提供的Redis安装包上传到虚拟机的任意目录&#xff1a; 例如&#xff0c;我放到了/tmp目录&#xff1a; 解压缩&#xff1a; tar -xzf redis-6.2.4.tar.gz解压后&#xff1…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...