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

用栈实现队列(图示超详解哦)

全文目录

  • 引言
  • 用栈实现队列
    • 题目介绍
    • 思路简述
    • 实现
      • 栈的部分
      • 队列的部分
        • 创建队列
        • 判断队列是否为空
        • 在队列尾入
        • 在队列头出
        • 访问队头元素
        • 释放队列
  • 总结

引言

在上一篇文章中,我们了解了用两个队列实现栈。在这篇问章中将继续介绍用两个栈实现队列的OJ练习:
用栈实现队列OJ链接

在本文中可能会需要借鉴到栈与队列的实现:
戳我看栈详解哦
戳我看队列详解哦

用栈实现队列

题目介绍

在这里插入图片描述
题目描述很简单:
通过两个栈实现队列存储数据的特点,即先进先出:

我们需要实现基本的队列操作:push、pop、top、empty、free:
void push(int x) 将元素 x 推到队列的末尾;
int pop() 从队列的开头移除并返回元素;
int peek() 返回队列开头的元素;
bool empty() 如果队列为空,返回 true ;否则,返回 false。

思路简述

与上一道题相同,这道题的难点同样在于结构:
如何实现pop时移除栈底的元素。由于栈是先进后出,所以栈底的元素是无法直接移除的。

我们就可以使用第二个栈,将栈中的元素依次取出,存入第二个栈中。由于栈是先进后出,所以当将一个栈中的元素依次取出,放进另一个栈中时,数据的顺序就会颠倒,这时在栈顶的元素就是最先入栈的元素,将这个元素移除即可;
也就是说,这个栈中栈顶的元素永远是最先入栈的元素,所以在这个栈中的元素没有全部移除之前,是不能在这个栈中再插入元素了,只能在原来的那个栈中插入;
我们发现,用两个栈来实现队列时,有一个栈只用于插入元素,有一个栈只用于移除元素,所以我们可以直接将前一个栈命名为push,后一个命名为pop;
如果pop栈为空,又需要移除元素时,才需要将push栈中的元素倒到pop栈中:
在这里插入图片描述

实现

栈的部分

在用两个栈实现队列之前,我们首先需要实现栈的接口。在需要用到栈的操作时直接复用即可。于栈的实现这里就不再赘述了,在前面的文章中已经详细的介绍过了。这里直接把前面实现过的栈的各种接口拷贝过来,包括用于定义队列的结构体:

typedef int STDataType;typedef struct Stack //表示栈
{STDataType* a;int top;int capacity;
}ST;//栈的部分
//初始化栈
void STInit(ST* ps)
{assert(ps);ps->a = (STDataType*)malloc(10 * sizeof(STDataType));assert(ps);ps->capacity = 10;ps->top = 0;
}
//判断栈是否为空
bool STEmpty(ST* ps)
{assert(ps);if (ps->top){return 0;}else{return 1;}
}
//压栈
void STPush(ST* ps, STDataType x)
{assert(ps);if (ps->top == ps->capacity){STDataType* ptr = (STDataType*)realloc(ps->a, (ps->capacity + 10) * sizeof(STDataType));assert(ptr);ps->a = ptr;ps->capacity += 10;}ps->a[ps->top] = x;ps->top++;
}
//出栈
void STPop(ST* ps)
{assert(ps && STEmpty(ps) == 0);ps->top--;
}
//计算栈中元素个数
int STSize(ST* ps)
{assert(ps);return ps->top;
}
//访问栈顶元素
STDataType STTop(ST* ps)
{assert(ps && STEmpty(ps) == 0);return ps->a[ps->top - 1];
}
//销毁栈
void STDestroy(ST* ps)
{assert(ps);free(ps->a);ps->capacity = 0;ps->top = 0;ps->a = NULL;
}

队列的部分

有了栈的实现后,我们首先应该创建两个栈:pushst与popst,用于插入与移除元素。并将这两个栈存放到一个结构体中,方便管理:

typedef struct //表示实现队列的两个栈
{ST pushst;ST popst;
} MyQueue;

创建队列

创建队列时,可以直接为前面声明的用于存放两个栈的结构体类型MyQueue动态开辟一块空间,然后再分别复用STInit初始化其中的两个栈即可:

//创建队列
MyQueue* myQueueCreate()
{MyQueue* pmq = (MyQueue*)malloc(sizeof(MyQueue));assert(pmq);STInit(&pmq->pushst);STInit(&pmq->popst);return pmq;
}

判断队列是否为空

队列为空,即两个栈均为空。
所以我们直接复用判断栈是否为空函数STEmpty,当两个栈均为空,即两个函数的返回值均为真时,返回真,否则返回假:

//判断队列是否为空:若为空返回true,非空返回false
bool myQueueEmpty(MyQueue* obj) 
{assert(obj);if (STEmpty(&obj->pushst) && STEmpty(&obj->popst))//当两个队列全为空即全为非0才为空,返回1;{return true;}else{return false;}
}

在队列尾入

任何时候插入元素时,在pushst栈中插入即可:

在这里插入图片描述

//在队列尾入
void myQueuePush(MyQueue* obj, int x) 
{assert(obj);STPush(&obj->pushst, x);
}

在队列头出

在队列头出时,永远从popst的栈顶移除即可,移除栈顶的元素时,复用STPop函数即可;
但是当popst为空时,就需要将pushst栈中的元素全部依次移动到popst栈中,我们可以通过复用STPush与STTop函数,将pushst栈顶的元素插入到popst中,然后再STPop移除pushst栈顶的元素即可。然后再pop掉popst的栈顶元素:
在这里插入图片描述

//从队列头出
int myQueuePop(MyQueue* obj) 
{assert(obj && myQueueEmpty(obj) == 0);STDataType ret = 0;if (STEmpty(&obj->popst))//当pop栈为空时,才将push栈中的元素转移过去{while (STEmpty(&obj->pushst) == 0){STPush(&obj->popst, STTop(&obj->pushst));STPop(&obj->pushst);}}ret = STTop(&obj->popst);STPop(&obj->popst);return ret;
}

访问队头元素

访问队头元素时只需要复用STTop函数,访问popst栈顶的元素即可;
但是当popst栈为空时,就需要将pushst中的元素全部倒过去后再访问:

//返回队列开头的元素
int myQueuePeek(MyQueue* obj) 
{assert(obj && myQueueEmpty(obj) == 0);//当pop为空时,只能转移后访问它;pop非空时可以直接访问pop的栈顶元素if (STEmpty(&obj->popst)){while (STEmpty(&obj->pushst) == 0){STPush(&obj->popst, STTop(&obj->pushst));STPop(&obj->pushst);}}return STTop(&obj->popst);
}

释放队列

释放队列时,分别释放两个栈即可。
当然,动态开辟的MyQueue型结构体也需要被释放:

//释放队列
void myQueueFree(MyQueue* obj) 
{STDestroy(&obj->pushst);STDestroy(&obj->popst);free(obj);
}

总结

到此,关于用两个栈实现队列的题目就介绍完了,相信通过这两道题目,大家对于栈与队列的结构都有了更好的理解
下一篇文章中将会介绍循环队列的实现,欢迎大家持续关注哦

如果大家认为我对某一部分没有介绍清楚或者某一部分出了问题,欢迎大家在评论区提出

如果本文对你有帮助,希望一键三连哦

希望与大家共同进步哦

相关文章:

用栈实现队列(图示超详解哦)

全文目录引言用栈实现队列题目介绍思路简述实现栈的部分队列的部分创建队列判断队列是否为空在队列尾入在队列头出访问队头元素释放队列总结引言 在上一篇文章中,我们了解了用两个队列实现栈。在这篇问章中将继续介绍用两个栈实现队列的OJ练习: 用栈实现…...

Spring - Spring 注解相关面试题总结

文章目录01. Spring 配置方式有几种?02. Spring 如何实现基于xml的配置方式?03. Spring 如何实现基于注解的配置?04. Spring 如何基于注解配置bean的作用范围?05. Spring Component, Controller, Repository, Service 注解有何区别…...

【数据结构】实现二叉树的基本操作

目录 1. 二叉树的基本操作 2. 具体实现 2.1 创建BinaryTree类以及简单创建一棵树 2.2 前序遍历 2.3 中序遍历 2.4 后序遍历 2.5 层序遍历 2.6 获取树中节点的个数 2.7 获取叶子节点的个数 2.8 获取第K层节点的个数 2.9 获取二叉树的高度 2.10 检测值为val的元素是否…...

代码随想录算法训练营第五十二天| ● 300.最长递增子序列 ● 674. 最长连续递增序列 ● 718. 最长重复子数组

300.最长递增子序列 看完题后的思路 dp[i] [0,i]子数组中,以nums[i]结尾的子序列的长度 dp[i]dp[j]1 j从i-1向0遍历,在所有nums[j]<nums[i]中dp[j]最大 初始化 dp[0]1 代码 class Solution {public int lengthOfLIS(int[] nums) {if (nums.length0){return 0;}int[] dpne…...

手机验证发送及其验证(基于springboot+redis)保姆级

在Java开发中&#xff0c;发送手机验证码时需要考虑以下几个问题&#xff1a; 验证码的有效期&#xff1a;验证码应该有一定的有效期&#xff0c;一般设置为几分钟或者十几分钟。过期的验证码应该被认为是无效的&#xff0c;不能用于验证用户身份。手机号码格式的校验&#xf…...

【JavaScript 逆向】数美滑块逆向分析

声明本文章中所有内容仅供学习交流&#xff0c;相关链接做了脱敏处理&#xff0c;若有侵权&#xff0c;请联系我立即删除&#xff01;案例目标验证码&#xff1a;aHR0cHM6Ly93d3cuaXNodW1laS5jb20vbmV3L3Byb2R1Y3QvdHcvY29kZQ以上均做了脱敏处理&#xff0c;Base64 编码及解码方…...

多任务之线程

文章目录一、多任务是什么&#xff1f;二、多任务-线程四、通过继承Tread类完成创建线程五、资源竞争六、同步与互斥锁七、对峙与避免死锁一、多任务是什么&#xff1f; 多个函数同时执行一件事情就是多任务&#xff0c;没有多任务的时候任务执行都是按照顺序的&#xff0c;而…...

(数字图像处理MATLAB+Python)第二章数字图像处理基础-第二节:色度学基础与颜色模型

文章目录一&#xff1a;颜色匹配二&#xff1a;CIE 1931-RGB系统三&#xff1a;CIE 1931标准色度系统四&#xff1a;CIE 1976Lab均匀颜色空间五&#xff1a;孟塞尔表色系统&#xff08;1&#xff09;孟塞尔明度(Value&#xff0c;记为V)&#xff08;2&#xff09;孟塞尔彩度(Ch…...

【华为OD机试 2023最新 】 网上商城优惠活动(C++)

文章目录 题目描述输入描述输出描述备注用例题目解析C++题目描述 某网上商场举办优惠活动,发布了满减、打折、无门槛3种优惠券,分别为: 每满100元优惠10元,无使用数限制,如100199元可以使用1张减10元,200299可使用2张减20元,以此类推;92折券,1次限使用1张,如100元,…...

记一次CentOS 8 部署packstack部署OpenStack失败案例,请直接看最后

首先你需要一台安装好CentOS8 的虚拟机&#xff0c;相关参数如图。两块网卡&#xff0c;网卡1 NAT IP 192.168.100.100 GW192.168.100.2 网卡2 可不做配置。能ping通百度。创建完成虚拟机记得打好快照。 开机编辑基本配置环境变量 [rootlocalhost ~]# nmcli connection show NA…...

【2023春招】美团技术岗笔试10min+AK

随手投递了前端&移动端,笔试2道算法+选择+行测题(为什么笔试会有行测题?) 目录 T1-火车栈结构 题意 输入描述 输出描述 样例 AC_Code T2-春游...

Echarts实现图表自适应屏幕分辨率

一&#xff1a;简介 之前做项目的时候要实现echarts图表随浏览器窗口大小变化而改变&#xff0c;echarts本身提供了一个resize()方法&#xff0c;然后我们需要用一个函数实现浏览器窗口监听&#xff0c;最初我选用的是window.onresize方法&#xff0c;当页面只有一个图表时可以…...

【2023年第十一届泰迪杯数据挖掘挑战赛】B题:产品订单的数据分析与需求预测 建模及python代码详解 问题一

相关链接 【2023年第十一届泰迪杯数据挖掘挑战赛】B题&#xff1a;产品订单的数据分析与需求预测 建模及python代码详解 问题一 【2023年第十一届泰迪杯数据挖掘挑战赛】B题&#xff1a;产品订单的数据分析与需求预测 建模及python代码详解 问题二 1 题目 一&#xff0e;问题…...

【蓝桥杯嵌入式】第十三届蓝桥杯嵌入式国赛客观题以及详细题解

题1 概念题。 USRAT&#xff1a;异步串口通信&#xff0c;常用于数据传输&#xff1b;SW-DP&#xff1a;SWD 的全称应该是 The Serial Wire Debug Port (SW-DP),也就是串行调试端口&#xff0c;是 >ARM 目前支持的两种调试端口之一&#xff1b;JTAG-DP&#xff1a;另一个调试…...

java中Map遍历的4种方式

目录 1、map.entrySet()方式 2、map.keySet()方式 3、map.values()方式 4、forEach方式 本文以如下map案例&#xff1a; Map<String, String> map new HashMap<>(); map.put("student1", "张三"); map.put("student2", "…...

GCC 编译器的主要组件和编译过程

主要组件&#xff1a; 分析器&#xff1a;分析器将源语言程序代码转换为汇编语言。因为要从一种格式转换为另一种格式&#xff08;C到汇编&#xff09;&#xff0c;所以分析器需要知道目标机器的汇编语言。 汇编器&#xff1a;汇编器将汇编语言代码转换为CPU可以执行字节码。 …...

蓝桥杯冲刺 - week2

文章目录&#x1f4ac;前言&#x1f332;day1最大和 (DP质因数分解)901. 滑雪 - 记忆化搜索&#x1f332;day21227. 分巧克力 - 二分&#x1f332;day31221. 四平方和 - 空间换时间1230. K倍区间&#x1f332;day41076. 迷宫问题 - 路径2017-迷宫-填空&#x1f332;day5848. 有…...

第十四届蓝桥杯三月真题刷题训练——第 20 天

目录 第 1 题&#xff1a;纸张尺寸 问题描述 输入格式 输出格式 样例输入1 样例输出1 样例输入 2 样例输出 2 运行限制 代码&#xff1a; 解析&#xff1a; 第 2 题&#xff1a;最大数字 第 3 题&#xff1a;全排列的价值_递推公式 问题描述 输入格式 输出格式…...

【C++】科普:C++中的浮点数怎么在计算机中表示?

这里我们以8.25这个数为例说明计算机时如何存取float类型的数据的&#xff1a; float a 8.25;引言 1. 所占位数 首先&#xff0c;明确一个概念&#xff0c;float类型的数据在常规计算机中通常占4个字节&#xff0c;也就是32位。其内存分布如图&#xff1a; 位字段说明所占位…...

Linux 多线程:多线程和多进程的对比

目录一、多进程优缺点二、多线程优缺点三、使用多执行流的场景在多任务处理中&#xff0c;我们既可以使用多进程&#xff0c;也可以使用多线程。但多进程和多线程并不是随意选择的&#xff0c;因为它们应对的场景不同&#xff0c;优缺点也不同。 一、多进程优缺点 多进程就是在…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...