当前位置: 首页 > 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…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

解读《网络安全法》最新修订,把握网络安全新趋势

《网络安全法》自2017年施行以来&#xff0c;在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂&#xff0c;网络攻击、数据泄露等事件频发&#xff0c;现行法律已难以完全适应新的风险挑战。 2025年3月28日&#xff0c;国家网信办会同相关部门起草了《网络安全…...

LabVIEW双光子成像系统技术

双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制&#xff0c;展现出显著的技术优势&#xff1a; 深层组织穿透能力&#xff1a;适用于活体组织深度成像 高分辨率观测性能&#xff1a;满足微观结构的精细研究需求 低光毒性特点&#xff1a;减少对样本的损伤…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...