【使用两个栈实现队列】
文章目录
- 一、栈和队列的基本特点
- 二、基本接口函数的实现
- 1.栈的接口
- 2.创建队列骨架
- 3.入队操作
- 4.取出队列元素
- 5.返回队首元素
- 6.判断队列是否为空
- 7.销毁队列
- 总结
一、栈和队列的基本特点
栈的特点是后进先出,而队列的特点是先进先出。
使用两个栈实现队列,必须具备队列的先进先出的功能。
举个例子:

向其中一个栈中放入4个元素,那么按照队列的特点,出队时是1先出队,所以需要把栈的所有元素全部出栈转移到空栈中。
再逐一出元素。
假如出栈一次后,又需要入栈,如下图:

则需要把元素存入空栈中,出栈的时候就出右边的非空栈。
出完右边的非空栈后,假如还想出栈,应该出的是5,那么就把左边的元素导入到右边的空栈,再出栈。

题目如下:
两个栈实现队列

二、基本接口函数的实现
1.栈的接口
typedef int STDataType;//采用顺序表来实现栈和队列
//采用链表形式来实现也可以,不过更加推荐顺序表,顺序表
//最大的优点就是支持随机访问typedef struct Stack
{STDataType* a;int top;int capacity;
}ST;void StackInit(ST* ps);
void StackDestroy(ST* ps);
void StackPush(ST* ps, STDataType x);
void StackPop(ST* ps);//取栈顶数据
STDataType StackTop(ST* ps);
int StackSize(ST* ps);
bool StackEmpty(ST* ps); //也可以用int作为类型返回值void StackPrint(const ST *ps);void StackInit(ST* ps)
{assert(ps);ps->a = NULL;ps->top = ps->capacity = 0;//top也可以给-1,给0的意思是,先给值,再++。---指向栈顶数据的下一个//top给-1是先++再给值。---指向栈顶数据。}void StackPush(ST* ps, STDataType x)
{assert(ps);if (ps->top == ps->capacity)//空间不足,增容{int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;STDataType* tmp = realloc(ps->a, sizeof(STDataType) * newcapacity);//当ps->a 为NULL时,realloc相当于malloc。不用分类讨论ps->a是否为空assert(tmp != NULL);ps->a = tmp;ps->capacity = newcapacity;}ps->a[ps->top] = x;ps->top++;}void StackDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;}
void StackPop(ST* ps)//取栈顶数据
{assert(ps);//assert(ps->top > 0);assert(!StackEmpty(ps));//也可以这样写ps->top--;//但是这里有问题,top会减到小于0,所以需要断言top要>0
}//取栈顶数据
STDataType StackTop(ST* ps)
{assert(ps);//这里也需要给定,top必须大于0,assert(ps->top > 0);return ps->a[ps->top - 1];//顺序表相当于数组,下标从0开始,并且top也是从0开始的,所以需要-1
}int StackSize(ST* ps)//返回栈的元素个数
{assert(ps);return ps->top;
}bool StackEmpty(ST* ps)//判断栈内是否还有元素
{assert(ps);//if (ps->top == 0)//{// return true;//}//else//{// return false;//}return ps->top == 0;//表达式为真,返回逻辑真,为假,返回逻辑假
}void StackPrint(const ST*ps)//栈要保证后进先出。
{assert(ps);for (int i = ps->top-1; i>=0; --i){printf("%d ",ps->a[i]);}printf("\n");
}
2.创建队列骨架
typedef struct {ST pushST;ST popST;
} MyQueue;MyQueue* myQueueCreate() {MyQueue*q = (MyQueue*)malloc(sizeof(MyQueue));StackInit(&q->pushST);StackInit(&q->popST);return q;
}
这里可以细致地将两个栈分为入数据栈(pushST)和出数据栈(popST),便于操作。
3.入队操作
void myQueuePush(MyQueue* obj, int x)
{StackPush(&obj->pushST,x);
}
4.取出队列元素
int myQueuePop(MyQueue* obj)
{//应该先要判断popST中是否有元素,如果有元素,那就直接pop掉//popST中的元素,如果没有元素,先全部导入进去,然后再popif(StackEmpty(&obj->popST)){while(!StackEmpty(&obj->pushST)){StackPush(&obj->popST,StackTop(&obj->pushST));StackPop(&obj->pushST);}}int top = StackTop(&obj->popST);StackPop(&obj->popST);return top;
}
注意,取出队列元素时,先判断popST栈是否为空,如果不为空,直接在这个栈中出元素。
如果为空,先将pushST栈的元素导入到popST栈,再从popST栈出元素
5.返回队首元素
//返回队列开头的元素
int myQueuePeek(MyQueue* obj)
{//如果popST还有元素,则直接在这里返回,如果没有元素,则应该先把pushST的元素全部导入PopST,再取栈顶元素if(StackEmpty(&obj->popST)){while(!StackEmpty(&obj->pushST)){StackPush(&obj->popST,StackTop(&obj->pushST));StackPop(&obj->pushST);}}return StackTop(&obj->popST);
}
这里也有需要注意的点:
返回队首元素应先判断pushST栈是否为空,如果不为空直接从这个栈返回栈顶元素,如果为空,应该先从pushST栈导入数据到popST,再从popST栈中出栈顶元素。
6.判断队列是否为空
bool myQueueEmpty(MyQueue* obj)
{return StackEmpty(&obj->pushST) && StackEmpty(&obj->popST);
}
判断队列是否为空,等同于判断完两个栈是否为空。
7.销毁队列
void myQueueFree(MyQueue* obj) {StackDestroy(&obj->pushST);StackDestroy(&obj->popST);free(obj);
}
先释放两个栈,再释放这两个栈所在的结构体。
总结
以上就是今天要讲的内容,本文简单介绍了两个栈实现队列的方法。
相关文章:
【使用两个栈实现队列】
文章目录一、栈和队列的基本特点二、基本接口函数的实现1.栈的接口2.创建队列骨架3.入队操作4.取出队列元素5.返回队首元素6.判断队列是否为空7.销毁队列总结一、栈和队列的基本特点 栈的特点是后进先出,而队列的特点是先进先出。 使用两个栈实现队列,必…...
web,h5海康视频接入监控视频流记录一
项目需求,web端实现海康监控视频对接接入,需实现实时预览,云台功能,回放功能。 web端要播放视频,有三种方式,一种是装浏览器装插件,一种是装客户端exe,还有就是无插件了。浏览器装插…...
做毕业设计,前端部分你需要掌握的6个核心技能
其实前端新手如果想要自己实现一套毕业设计项目并非简单的事,因为之前很多人一直还停留在知识点的阶段,而且管理系统和C端网站都需要开发,但现在需要点连成线了。所以在启动项目开发之前呢,针对前端部分,我列举一些非常…...
Read book Netty in action(Chapter VIII)--EventLoop and thread model
前言 简单地说,线程模型指定了操作系统、编程语言、框架或者应用程序的上下文中的线程管理的关键方面。显而易见地,如何以及何时创建线程将对应用程序代码的执行产生显著的影响,因此开发人员需要理解与不同模型相关的权衡。无论是他们自己选…...
番外11:使用ADS对射频功率放大器进行非线性测试3(使用带宽5MHz的WCDMA信号进行ACLR测试)
番外11:使用ADS对射频功率放大器进行非线性测试3(使用带宽5MHz的WCDMA信号进行ACLR测试) 其他测试: 番外9:使用ADS对射频功率放大器进行非线性测试1(以IMD3测试为例) 番外10:使用AD…...
Linux libpqxx 库安装及使用
记录一下linux安装 libpqxx遇到的一些问题 1.准备安装包: 1.准备安装包,以libpqxx-4.0.1.tar.gz为例子 链接如下:https://launchpad.net/libpqxx/milestone/4.0.1 2.上传并安装 上传到安装目录并安装,我是放到/use/local下面 c…...
如何使用COM-Hunter检测持久化COM劫持漏洞
关于COM-Hunter COM- Hunter是一款针对持久化COM劫持漏洞的安全检测工具,该工具基于C#语言开发,可以帮助广大研究人员通过持久化COM劫持技术来检测目标应用程序的安全性。 关于COM劫持 微软在Windows 3.11中引入了(Component Object Model, COM)&…...
Cartesi 举办的2023 黑客马拉松
Cartesi 是具有 Linux 运行时的特定于应用程序的Rollups执行层。Cartesi 的特定应用程序 Optimistic Rollup 框架使区块链堆栈足够强大,开发人员可以构建计算密集型和以前不可能的去中心化实例。Cartesi 的 RISC-V 虚拟机支持 Linux 运行时环境,允许像你…...
架构篇--代码质量手册
目前团队缺少SA(研发经理)的角色,大家代码写的有点随意,老板让我写一份开发手册。嗯!!!当时我稍微纠结了一下,感觉这个似乎不是我的工作范畴,但是本着"我就是块砖&a…...
那些年用过的IDEA插件
今天和大家分享一下经常使用的IDEA的插件,希望有所帮助。一、IDEA插件CodeGlance2显示代码缩略图插件,方便查看代码。Lombok用于编译期间自动生成getter、setter、构造、toString等方法,简化代码。Mybatis Builder或MybatisXMapper接口和xml双…...
python+requests实现接口自动化测试
这两天一直在找直接用python做接口自动化的方法,在网上也搜了一些博客参考,今天自己动手试了一下。 一、整体结构 上图是项目的目录结构,下面主要介绍下每个目录的作用。 Common:公共方法:主要放置公共的操作的类,比如数据库sqlhe…...
rtthread 线程
创建动态线程最简单代码 #include <rtthread.h>//包含头文件static rt_thread_t thread1 RT_NULL; //创建线程控制块指针,指向空static void thread1_entry(void *parameter)//线程入口(干什么) {rt_kprintf("do something"…...
伯恩光学再成被执行人:多次因劳动纠纷被起诉,曾冲刺港交所上市
近日,贝多财经从天眼查APP了解到,伯恩光学(深圳)有限公司(下称“伯恩光学”)因《伯恩光学(深圳)有限公司与温*燕劳动合同纠纷的案件》一事,被广东省深圳市龙岗区人民法院…...
mysql基础操作2
通配符_:一个任意字符,like ‘张_’%:任意长度的字符串,like ‘co%’,‘%co’,‘%co%’【】:括号中所指定范围内的一个字符,like ‘9W0【1-2】’【^】:不在括号中所指定范…...
指针的进阶【下篇】
文章目录📀8.指向函数指针数组的指针📀9.回调函数📀8.指向函数指针数组的指针 🌰请看代码与注释👇 int Add(int x, int y) {return x y; } int Sub(int x, int y) {return x - y; } int main() {int (*pf)(int, int…...
不同序列模型的输入和输出总结
不同序列模型的输入和输出总结 文章目录不同序列模型的输入和输出总结RNNLSTMGRURNN RNN 是迭代输出: 输入第一个 -> 输出第二个, 输入第二个 -> 输出第三个, 输出倒数第二个 -> 输出最后一个。 LSTM LSTM 也是迭代输出ÿ…...
基于神经网络补偿的主动悬架自适应控制
目录 前言 1. 1/4悬架模型 2.仿真分析 2.1仿真模型 2.2仿真结果 2.1 形① 2.2 形② 3. 总结 前言 上两篇博客我们介绍了神经网络补偿控制律的仿真测试,从仿真结果我们可以得知神经网络具有逼近扰动,并将其补偿的作用。 上两篇文章链接…...
什么是链表,如何实现?(单链表篇)
欢迎来到 Claffic 的博客 💞💞💞 “仅仅活着是不够的,还需要有阳光,自由和花的芬芳。” 前言: 在日常使用的网站和软件中,列表属于最常见的一种东西了,其实现形式有顺序表࿰…...
探针台简介
探针台,是我们半导体实验室电学性能测试的常用设备,也是各大实验室以及芯片设计、封装测试的熟客。设备具备各项优势,高性能低成本,用途广,操作方便,在不同测试环境下,测试结果稳定,…...
ABAP 辨析 标准表|排序表|哈希表
1、文档介绍 本文档将介绍内表的区别和用法,涉及标准表、排序表、哈希表 2、用法与区别 2.1、内表种类 内表顶层为任意表,任意表分为索引表和哈希表,索引表又可分为标准表和排序表,结构如图: 2.2、内表用法 2.2.1…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...
如何配置一个sql server使得其它用户可以通过excel odbc获取数据
要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据,你需要完成以下配置步骤: ✅ 一、在 SQL Server 端配置(服务器设置) 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到:SQL Server 网络配…...
Monorepo架构: Nx Cloud 扩展能力与缓存加速
借助 Nx Cloud 实现项目协同与加速构建 1 ) 缓存工作原理分析 在了解了本地缓存和远程缓存之后,我们来探究缓存是如何工作的。以计算文件的哈希串为例,若后续运行任务时文件哈希串未变,系统会直接使用对应的输出和制品文件。 2 …...
针对药品仓库的效期管理问题,如何利用WMS系统“破局”
案例: 某医药分销企业,主要经营各类药品的批发与零售。由于药品的特殊性,效期管理至关重要,但该企业一直面临效期问题的困扰。在未使用WMS系统之前,其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...
【实施指南】Android客户端HTTPS双向认证实施指南
🔐 一、所需准备材料 证书文件(6类核心文件) 类型 格式 作用 Android端要求 CA根证书 .crt/.pem 验证服务器/客户端证书合法性 需预置到Android信任库 服务器证书 .crt 服务器身份证明 客户端需持有以验证服务器 客户端证书 .crt 客户端身份…...
