栈和队列——用队列实现栈

题目中给出,让我们应用两个队列实现栈,首先我们先来想一下,栈是先进后出,队列是先进先出。所以我们就需要应用两个队列来回导才能实现栈的特点。因为这道题是基于队列来实现的,所以在下方若有看不懂的函数名称可以去栈和队列(二)中找到。

1.MyStrack

首先我们需要在结构体中存储我们的两个队列,后续方便通过结构体来调用两个队列。

typedef struct 
{Queue q1;Queue q2;
} MyStack;

2.myStackCreate()

对其进行初始化,首先我们需要先开辟一块空间用来存储两个队列。然后我们调用QueueInit()函数来对两个队列进行初始化。

MyStack* myStackCreate() 
{MyStack*obj=(MyStack*)malloc(sizeof(MyStack));QueueInit(&(obj->q1));QueueInit(&(obj->q2));return obj;
}

3.myStackPush()

对栈进行插入,首先我们需要调用QueueEmpty()函数判断两个队列哪个不为空,再调用QueuePush()函数将数据直接插入到不为空的那个队列里就可以了。

void myStackPush(MyStack* obj, int x) 
{if(!QueueEmpty(&(obj->q1))){QueuePush(&(obj->q1),x);}else{QueuePush(&(obj->q2),x);}
}

4.myStackPop()

因为我们已经知道栈的删除是删除后进的数据,队列的删除是删除先进的数据。其删除的位置不同,所以不能混为一谈。所以我们需要把非空的队列中的前size-1个数据都挪到空的队列中。首先我们就需要先判断那个队列是空的。所以,依据我们之前做过的题,我们可以使用假设法,先假设q1为空,若q1不为空,再将空的改为q2。现在我们就用empty和nonempty来代表空队列和非空队列了。然后我们应用QueuePush()函数和QueueFront()函数来将非空队列中的头数据插入到空队列中,直到非空链表中的数据个数为1时停止,取出非空队列中的数据,就是我们需要的数据。

int myStackPop(MyStack* obj) 
{Queue*empty=&(obj->q1);Queue*nonempty=&(obj->q2);if(!QueueEmpty(&(obj->q1))){empty=&(obj->q2);nonempty=&(obj->q1);}while(QueueSize(nonempty)>1){QueuePush(empty,QueueFront(nonempty));QueuePop(nonempty);}int top=QueueFront(nonempty);QueuePop(nonempty);return top;
}

5.myStackTop()

由于栈是先进后出,队列是先进先出,所以栈的Top就是队列中后进的那个数据。所以我们首先需要判断哪个队列为非空队列,再调用QueueBack()函数返回非空队列中的尾数据就可以了。

int myStackTop(MyStack* obj) 
{if(!QueueEmpty(&(obj->q1))){return QueueBack(&(obj->q1));}else{return QueueBack(&(obj->q2));}
}

6.myStackEmpty()

判断队列是否为空,需要两个队列同时为空,所以只需要调用QueueEmpty()函数,并返回两个队列进行与运算的值就可以了。

bool myStackEmpty(MyStack* obj) 
{return QueueEmpty(&(obj->q1))&&QueueEmpty(&(obj->q2));   
}

7.myStackFree()

由于我们刚刚将两个队列存储在了一个结构体中,所以在销毁时不能直接将结构体销毁,而是应该先销毁两个队列,再销毁结构体。

void myStackFree(MyStack* obj) 
{QueueDestory(&(obj->q1));QueueDestory(&(obj->q2));free(obj);
}

总结

整道题的基本思路与代码就讲解完毕了,下面附上本题的完整代码,如果大家感兴趣的话可以自行尝试哦~

typedef int QDataType;
typedef struct QueueNode
{QDataType val;struct QueueNode* next;
}QNode;typedef struct Queue
{QNode* phead;QNode* ptail;int size;
}Queue;//队列的初始化
void QueueInit(Queue* pq);
//队列的插入
void QueuePush(Queue* pq, QDataType x);
//队列的删除
void QueuePop(Queue* pq);
//统计队列内的数据个数
int QueueSize(Queue* pq);
//获取队列的头数据
QDataType QueueFront(Queue* pq);
//获取队列的尾数据
QDataType QueueBack(Queue* pq);
//队列的判空
bool QueueEmpty(Queue* pq);
//队列的销毁
void QueueDestory(Queue* pq);//队列的初始化
void QueueInit(Queue* pq)
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}
//队列的插入
void QueuePush(Queue* pq, QDataType x)
{assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");exit(1);}newnode->next = NULL;newnode->val = x;if (pq->ptail == NULL){pq->phead = pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}
//队列的删除
void QueuePop(Queue* pq)
{assert(pq);assert(pq->size != 0);//方法一:后判是否为只剩一个节点//QNode* next = pq->phead->next;//free(pq->phead);//pq->phead = next;//if (pq->phead == NULL)//{//	pq->ptail = NULL;//}//pq->size--;//方法二:先判是否为只剩一个节点if (pq->phead->next == NULL){pq->phead = pq->ptail = NULL;pq->size = 0;}else{QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;pq->size--;}
}//统计队列内的数据个数
int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}//获取队列的头数据
QDataType QueueFront(Queue* pq)
{assert(pq);assert(pq->phead);return pq->phead->val;
}
//获取队列的尾数据
QDataType QueueBack(Queue* pq)
{assert(pq);assert(pq->ptail);return pq->ptail->val;
}//队列的判空
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->size == 0;}//队列的销毁
void QueueDestory(Queue* pq)
{assert(pq);QNode* pcur = pq->phead;while (pcur){QNode* next = pcur->next;free(pcur);pcur = next;}pq->phead = pq->ptail = NULL;pq->size = 0;
}typedef struct 
{Queue q1;Queue q2;
} MyStack;MyStack* myStackCreate() 
{MyStack*obj=(MyStack*)malloc(sizeof(MyStack));QueueInit(&(obj->q1));QueueInit(&(obj->q2));return obj;
}void myStackPush(MyStack* obj, int x) 
{if(!QueueEmpty(&(obj->q1))){QueuePush(&(obj->q1),x);}else{QueuePush(&(obj->q2),x);}
}int myStackPop(MyStack* obj) 
{Queue*empty=&(obj->q1);Queue*nonempty=&(obj->q2);if(!QueueEmpty(&(obj->q1))){empty=&(obj->q2);nonempty=&(obj->q1);}while(QueueSize(nonempty)>1){QueuePush(empty,QueueFront(nonempty));QueuePop(nonempty);}int top=QueueFront(nonempty);QueuePop(nonempty);return top;
}int myStackTop(MyStack* obj) 
{if(!QueueEmpty(&(obj->q1))){return QueueBack(&(obj->q1));}else{return QueueBack(&(obj->q2));}
}bool myStackEmpty(MyStack* obj) 
{return QueueEmpty(&(obj->q1))&&QueueEmpty(&(obj->q2));   
}void myStackFree(MyStack* obj) 
{QueueDestory(&(obj->q1));QueueDestory(&(obj->q2));free(obj);
}/*** Your MyStack struct will be instantiated and called as such:* MyStack* obj = myStackCreate();* myStackPush(obj, x);* int param_2 = myStackPop(obj);* int param_3 = myStackTop(obj);* bool param_4 = myStackEmpty(obj);* myStackFree(obj);
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/414176.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【indirect 函数 ★二级下拉菜单】

Indirect 函数 🌼indirect函数参数🌼应用:🌼跨表引用同一单元格🌼二级下拉列表 🌼indirect函数参数 返回⬅️【文本字符串所指定的引用】 INDIRECT(ref_text,[a1]) 其中【ref_text】是引用的文本 [a1] 是…

网络安全实训六(靶机实例DC-3)

1 信息收集 1.1 获取靶机IP 1.2 扫描靶机网站的目录 1.3 扫描端口和服务器信息 1.4 进入网站 1.5 在msf中给搜索joomla扫描器 1.6 设置参数查看joomla版本信息 1.7 按照版本号搜索漏洞 1.8 查看漏洞使用 2 渗透 2.1 查看是否存在SQL注入 2.2 获取到数据库信息 2.3 爆破列表 2…

盘点java8 stream中隐藏的函数式接口

shigen坚持更新文章的博客写手,记录成长,分享认知,留住感动。个人IP:shigen 提到函数式接口,最常见的就是lambda表达式,IDEA也有智能的提示: 最后改成这样的就是最简洁的、IDEA希望的风格&#…

【我要成为配环境高手】Visual Studio中Qt安装与配置(无伤速通)

1.下载安装Qt和VSIX插件 2.本地环境变量配置 添加如下: D:\ProgramData\Qt\Qt5.14.2\5.14.2\msvc2017_64\libD:\ProgramData\Qt\Qt5.14.2\5.14.2\msvc2017_64\bin3.VS配置 ⭐项目右键->属性->调试->环境,添加如下:(很重要&#x…

随笔十、音频扩展模块测试

本项测试简单,对购买的音频扩展模块进行录音放音测试 按照使用说明,连接音频小板,一个喇叭一个麦克风,4根线,buildroot系统镜像 录音测试 rootRK356X:/# arecord -c 1 -r 44100 -f S16_LE /tmp/record.wav Recording …

【面试五】PID控制算法

一、 PID算法简介 PID(Proportional-Integral-Derivative)控制算法是一种经典的反馈控制方法,广泛应用于自动控制系统,例如温度控制、速度控制、位置控制等。 PID控制算法的核心包含三个部分:比例项(P&…

Linux基础(包括centos7安装、linux基础命令、vi编辑器)

一、安装CentOS7 需要:1、VMware Workstation;2、CentOS7镜像 1、安装镜像 2、虚拟机配置 开启虚拟机,鼠标从vm中移出来用快捷键ctrlalt 点击开始安装,设置密码,等待安装完成,,重启。 3、注意事项 如果没…

CAN总线简介

CAN 是 Controller Area Network 的缩写(以下称为 CAN),是 ISO国际标准化的串行通信协议。 历史背景 CAN 最初出现在80年代末的汽车工业中,由德国 Bosch 公司最先提出。当时,由于消费者对于汽车功能的要求越来越多&a…

android仿assistivetouch悬浮窗实现(带功能实现)

一、悬浮窗点击后的界面: 主要有四个功能,返回、应用程序、退出和主界面。其他功能也可以类似添加。 界面布局代码就不贴出来了,源码(切记需要签名才能让功能实现):下载地址 二、主要是检测系统启动或者a…

动态规划法例题

第一个空,用手工计算,可以用贪心法 先选择价值最大的物品,有两个价值是6的物品,重量合计246 剩余4个空间,只能放重量为2的物品,一共是66315 第二个空,需要将所有物品都放进背包舱室&#xff…

基于Python的量化交易回测框架Backtrader初识记录(一)

版权声明:本文为博主原创文章,如需转载请贴上原博文链接:基于Python的量化交易回测框架Backtrader初识记录(一)-CSDN博客 前言:近期以来,对股市数据获取及预处理算是告一段落,下一步…

OpenCV绘图函数(5)绘制标记函数drawMarker()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 cv::drawMarker 函数在 OpenCV 中用于在一个给定的位置上绘制标记。目前支持几种不同的标记类型,具体信息可以参考 MarkerTypes 函数…

【C++ | 设计模式】观察者模式的详解与实现

1.概念 观察者模式(Observer Pattern)是一种行为型设计模式,它的核心思想是定义对象间的一对多依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会收到通知并自动更新。这个模式在现实生活中非常常见&#…

Selenium的四种部署方式详解

关于selenium 的部署,我在网上找了很多,基本上都没有提到或是说的比较清晰的。当时我一直有个困惑:测试的脚本代码,是放在跟浏览器同一台机器上呢,还是放在Application Server上? 在官方开发文档中&#x…

从0开始深度学习(2)——自动微分

1 微积分 1.1 导数和微分 略 1.2 偏导数 略 1.3 梯度(gradient) 1.3.1 定义 对于一个多变量函数 f ( x 1 , x 2 , … , x n ) f\left(x_{1}, x_{2}, \ldots, x_{n}\right) f(x1​,x2​,…,xn​)其中点 a ( a 1 , a 2 , … , a n ) \mathbf{a}(a_…

YGG深海传奇,创造财富无限可能!

随著区块链技术的创新与游戏产业的深度融合,GameFi赛道迅速崛起,成为全球投资者与玩家瞩目的新兴领域。 成立于2020年的Yield Guild Games(YGG),作为全球区块链游戏领域的先锋公会之一,也加入到向去中心化经济模式的转型浪潮当中。…

E. Sheep Eat Wolves

https://codeforces.com/gym/104869/problem/E 赛时队友想贪心,贪不了一点,我想了数学办法每次都送固定的发现送过去就不满足了 赛后补,暴力做O(n4) 至少要几次才能把安全所有羊送到对岸去 考虑最短路,bfs,用数组存下所有状态 …

17:4层板层叠设置

层叠设置参考PCB专栏 设置平面内缩 GND内缩设置20mil0.508mm 电源层内缩设置要比GND内缩大,设置40mil1mm

米家商城主题 html 页面源码分享,可用于网页设计作业

使用技术: HTML, CSS , Javascript 项目亮点: 1. 仿照米家商城页面布局所做的页面样式结构 2. 首页放置了可自动切换的轮播图 3. 登录页有表单结构,并且有切换的动画效果 4. 包含实时的动态时间,使用 js 实现 5. 页面布局清…

Datawhale X 李宏毅苹果书AI夏令营深度学习详解入门Task02

本文了解深度学习详解中的线性模型 本文了解深度学习详解中的线性模型将围绕梯度下降优化、线性模型的局限性、改进模型以及深度学习模型等关键要点展开讨论。 一、梯度下降优化 梯度下降是深度学习中常用的优化算法,它通过不断调整模型的参数,使得损失函…