数据结构 | 栈与队列
🔥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;
}
入队:
用链表的尾插法进行入队
//入队,尾部插入法
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;
}
相关文章:
数据结构 | 栈与队列
🔥Go for it!🔥 📝个人主页:按键难防 📫 如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀 📖系列专栏:数据结构与算法 ὒ…...
Redux 源码分析
Redux 目录结构 redux ├─ .babelrc.js ├─ .editorconfig ├─ .gitignore …...
第五十二章 BFS进阶(二)——双向广搜
第五十二章 BFS进阶(二)——双向广搜一、双向广搜1、优越之处2、实现逻辑3、复杂度分析二、例题1、问题2、分析3、代码一、双向广搜 1、优越之处 双向广搜是指我们从终点和起点同时开始搜索,当二者到达同一个中间状态的时候,即相…...
业务建模题
一. 单选题:1.在活动图中负责在一个活动节点执行完毕后切换到另一个节点的元素是( A)。A.控制流 B.对象流 C.判断节点 D.扩展区城2.以下说法错误的是(C)。A.活动图中的开始标记一般只有一一个,而终止标记可能有多个B.判断节点的出口条件必须保证不互相重复,并且不缺…...
电子秤专用模拟数字(AD)转换器芯片HX711介绍
HX711简介HX711是一款专为高精度电子秤而设计的24 位A/D 转换器芯片。与同类型其它芯片相比,该芯片集成了包括稳压电源、片内时钟振荡器等其它同类型芯片所需要的外围电路,具有集成度高、响应速度快、抗干扰性强等优点。降低了电子秤的整机成本ÿ…...
微服务 RocketMQ-延时消息 消息过滤 管控台搜索问题
~~微服务 RocketMQ-延时消息 消息过滤 管控台搜索问题~~ RocketMQ-延时消息实现延时消息RocketMQ-消息过滤Tag标签过滤SQL标签过滤管控台搜索问题RocketMQ-延时消息 给消息设置延时时间,到一定时间,消费者才能消费的到,中间件内部通过每秒钟扫…...
js发送邮件(node.js)
以前看别人博客留言或者评论文章时必须填写邮箱信息,感觉甚是麻烦。 后来才知道是为了在博主回复后让访客收到邮件,用心良苦。 于是我也在新增留言和文章评论的接口里,新增了给自己发送邮件提醒的功能。 我用的QQ邮箱,具体如下…...
English Learning - Day58 一周高频问题汇总 2023.2.12 周日
English Learning - Day58 一周高频问题汇总 2023.2.12 周日这周主要内容继续说说状语从句结果状语从句这周主要内容 DAY58【周日总结】 一周高频问题汇总 (打卡作业详见 Day59) 一近期主要讲了 一 01.主动脉修饰 以下是最常问到的知识点拓展ÿ…...
【微电网】基于风光储能和需求响应的微电网日前经济调度(Python代码实现)
目录 1 概述 2 知识点及数学模型 3 算例实现 3.1算例介绍 3.2风光参与的模型求解 3.3 风光和储能参与的模型求解 3.5 风光储能和需求响应都参与模型求解 3.6 结果分析对比 4 Python代码及算例数据 1 概述 近年来,微电网、清洁能源等已成为全球关注的热点…...
四种方式的MySQL安装
mysql安装常见的方法有四种序号 安装方式 说明1 yum\rpm简单、快速,不能定制参数2二进制 解压,简单配置就可使用 免安装 mysql-a.b.c-linux2.x-x86_64.tar.gz3源码编译 可以定制参数,安装时间长 mysql-a.b.c.tar.gz4源码制成rpm包 把源码制…...
软考高级信息系统项目管理师系列之九:项目范围管理
软考高级信息系统项目管理师系列之九:项目范围管理 一、范围管理输入、输出、工具和技术表二、范围管理概述三、规划范围管理四、收集需求1.收集需求:2.需求分类3.收集需求的工具与技术4.收集需求过程主要输出5.需求文件内容6.需求管理7.可跟踪性8.双向可跟踪性9.需求跟踪矩阵…...
【项目精选】javaEE健康管理系统(论文+开题报告+答辩PPT+源代码+数据库+讲解视频)
点击下载源码 javaEE健康管理系统主要功能包括:教师登录退出、教师饮食管理、教师健康日志、体检管理等等。本系统结构如下: (1)用户模块: 实现登录功能 实现用户登录的退出 实现用户注册 (2)教…...
ctfshow nodejs
web 334 大小写转换特殊字符绕过。 “ı”.toUpperCase() ‘I’,“ſ”.toUpperCase() ‘S’。 “K”.toLowerCase() ‘k’. payload: CTFſHOW 123456web 335 通过源码可知 eval(xxx),eval 中可以执行 js 代码,那么我们可以依此执行系…...
无线传感器原理及方法|重点理论知识|2021年19级|期末考试
Min-Max定位 【P63】 最小最大法的基本思想是依据未知节点到各锚节点的距离测量值及锚节点的坐标构造若干个边界框,即以参考节点为圆心,未知节点到该锚节点的距离测量值为半径所构成圆的外接矩形,计算外接矩形的质心为未知节点的估计坐标。 多边定位法的浮点运算量大,计算代…...
带你写出符合 Promise/A+ 规范 Promise 的源码
Promise是前端面试中的高频问题,如果你能根据PromiseA的规范,写出符合规范的源码,那么我想,对于面试中的Promise相关的问题,都能够给出比较完美的答案。 我的建议是,对照规范多写几次实现,也许…...
回流与重绘
触发回流与重绘条件👉回流当渲染树中部分或者全部元素的尺寸、结构或者属性发生变化时,浏览器会重新渲染部分或者全部文档的过程就称为 回流。引起回流原因1.页面的首次渲染2.浏览器的窗口大小发生变化3.元素的内容发生变化4.元素的尺寸或者位置发生变化…...
openpyxl表格的简单实用
示例:创建简单的电子表格和条形图 在这个例子中,我们将从头开始创建一个工作表并添加一些数据,然后绘制它。我们还将探索一些有限的单元格样式和格式。 我们将在工作表上输入的数据如下: 首先,让我们加载 openpyxl 并创建一个新工作簿。并获取活动表。我们还将输入我们…...
【寒假day4】leetcode刷题
🌈一、选择题❤1.下列哪一个是析构函数的特征( )。A: 析构函数定义只能在类体内 B: 一个类中只能定义一个析构函数 C: 析构函数名与类名相同 D: 析构函数可以有一个或多个参数答案:B答案解析:析构函数是构造函…...
【竞赛题】6355. 统计公平数对的数目
题目: 给你一个下标从 0 开始、长度为 n 的整数数组 nums ,和两个整数 lower 和 upper ,返回 公平数对的数目 。 如果 (i, j) 数对满足以下情况,则认为它是一个 公平数对 : 0 < i < j < n,且 l…...
Redis集群搭建(主从、哨兵、分片)
1.单机安装Redis 首先需要安装Redis所需要的依赖: yum install -y gcc tcl然后将课前资料提供的Redis安装包上传到虚拟机的任意目录: 例如,我放到了/tmp目录: 解压缩: tar -xzf redis-6.2.4.tar.gz解压后࿱…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...
