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

用队列实现栈

前置学习:栈和队列分别的基本实现

可以参考:https://blog.csdn.net/xpcxpt/article/details/148481903?spm=1001.2014.3001.5501

https://blog.csdn.net/xpcxpt/article/details/148500318?spm=1001.2014.3001.5501

目录:

1.用队列实现栈

2.取栈顶元素

3.判断栈是否为空

4.销毁栈

5.代码

1.用队列实现栈

首先要调用队列的一系列前置函数

栈是后进先出,但是队列是先进先出,实现方法如下:
创建两个队列,分别为队列1和队列2,初始情况下,数据都在队列1中。

将数据从队列1移到队列2,剩下一个数据,那就是栈顶的数据。

重复以上行为,最终用队列实现栈。

下面开始详细实现:

首先创建两个队列:

接下来对两个队列进行初始化:

进行判空操作,如果队列1为空,那就往队列1里面插入数据,不然就往队列2里面插入数据:

按照思路,我们需要在两个队列间交换数据,但是我们不知道那个为空,所以使用假设法,假设队列1为空,如果不成立,那么队列2就为空:

这个时候其中一个队列是空的,另一个是非空的,我们将非空的队列的数据移到空的队列,只留一个,那个就是我们需要的栈顶的元素,至此,成功用队列实现栈:

2.取栈顶元素

这个很简单,找到非空队列,然后返回元素:

3.判断栈是否为空

只有两个队列都为空,才是空:

4.销毁栈

销毁不能直接销毁总体,要分别销毁:

5.代码

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
typedef int QDataType;
typedef struct QueueNode
{struct QueueNode* next;QDataType val;
}QNode;typedef struct Queue
{QNode* phead;QNode* ptail;int size;
}Queue;void QueueInit(Queue* pq);//初始化
void QueueDestroy(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 QueueInit(Queue* pq)
{assert(pq);//判断是否为空pq->phead = NULL;//初始化指向NULLpq->ptail = NULL;//初始化指向NULLpq->size = 0;//初始的时候,值为0
}
void QueuePush(Queue* pq, QDataType x)
{QNode* newnode = (QNode*)malloc(sizeof(QNode));//创建一个新节点if (newnode == NULL)//判断是否创建成功{perror("malloc fail");return;}newnode->next = NULL;//新节点的next指针为NULLnewnode->val = x;//它的值为给的xif (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);if (pq->phead->next==NULL)//是否链表中只有一个节点{free(pq->phead);pq->phead = pq->ptail = NULL;//都为NULL}else//链表中不止一个节点{QNode* tmp = pq->phead->next;//临时变量存放新的头结点free(pq->phead);pq->phead = tmp;}pq->size--;//删除节点,size要减少1
}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 QueueDestroy(Queue* pq)
{assert(pq);//判断是否为空QNode* cur = pq->phead;//创建一个额外指针指向头结点while (cur)//遍历链表{QNode* next = cur->next;//临时变量存放新的头结点free(cur);//原本头结点要被销毁掉cur = next;}pq->phead = pq->ptail = NULL;//全部节点销毁完,都置于空,防止成为野指针pq->size = 0;//size也变成0
}typedef struct {Queue q1;Queue q2;
} MyStack;MyStack* myStackCreate() {MyStack* pst=(MyStack*)malloc(sizeof(MyStack));//malloc开辟空间QueueInit(&(pst->q1));//对q1初始化QueueInit(&(pst->q2));//对q2初始化return pst;
}void myStackPush(MyStack* obj, int x) {if(!QueueEmpty(&(obj ->q1)))//队列1为空,就往队列1里面插入{QueuePush(&(obj->q1),x);}else//队列1不为空,就往队列2里面插入{QueuePush(&(obj->q2),x);}
}int myStackPop(MyStack* obj) {//假设法Queue* empty=&(obj->q1);//假设队列1是空的Queue* nonEmpty=&(obj->q2);//那么队列2就不是空的if(!QueueEmpty(&(obj->q1))){//判空函数判断,如果判空函数返回fasle,代表队列1不为空,这个时候!反转意思,所以if的括号内返回ture,执行运算//需要交换nonEmpty=&(obj->q1);//队列1非空empty=&(obj->q2);//队列2为空}//不为空的队列的前size-1个数据导入另一个队列,随后最后一个就是栈顶数据while(QueueSize(nonEmpty)>1)//非空队列留一个元素,就是栈顶的数据{QueuePush(empty,QueueFront(nonEmpty));//将非空数据插入空队列QueuePop(nonEmpty);}//这个时候还剩一个数据,他就是栈顶数据,将他返回,然后删除int top= QueueFront(nonEmpty);//top接受栈顶数据QueuePop(nonEmpty);//把他删除return  top;//返回栈顶数据
}int myStackTop(MyStack* obj) {if(!QueueEmpty(&(obj->q1))){//判空函数判断,如果判空函数返回fasle,代表队列1不为空,这个时候!反转意思,所以if的括号内返回ture,执行运算//这个时候队列1非空,取栈顶元素return QueueBack(&(obj->q1));}else{//这个时候队列2非空,取栈顶元素return QueueBack(&(obj->q2));}
}bool myStackEmpty(MyStack* obj) {return QueueEmpty(&(obj->q1)) && QueueEmpty(&(obj->q2));//两个都为空才是空
}void myStackFree(MyStack* obj) {QueueDestroy(&(obj->q1));QueueDestroy(&(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.xdnf.cn/news/919585.html

相关文章:

  • NT6打印机共享修复工具Fixprint系统补丁
  • React Hooks 示例项目
  • phosphobot开源程序是控制您的 SO-100 和 SO-101 机器人并训练 VLA AI 机器人开源模型
  • 《探秘跨网段局域网IP广播:解锁网络通信的新姿势》
  • OCR MLLM Evaluation
  • 复制与图片文件同名的标签文件到目标路径
  • 使用Caddy在Ubuntu 22.04上配置HTTPS反向代理
  • CKA考试知识点分享(2)---ingress
  • IT学习方法与资料分享
  • JDK17 Http Request 异步处理 源码刨析
  • 2012-2023年 上市公司-知识重组创造、知识重组再利用数据-社科经管实证数据
  • MVCC多版本并发控制
  • 81 实战一:给root目录扩容
  • SDC命令详解:使用set_port_fanout_number命令进行约束
  • robot_lab train的整体逻辑
  • 判断一个或者多个软件是否安装,如果没有则自动安装
  • 使用 Ansible 在 Windows 服务器上安装 SSL 证书系列之二
  • 无法与IP建立连接,未能下载VSCode服务器
  • 前端高频面试题2:浏览器/计算机网络
  • 零基础在实践中学习网络安全-皮卡丘靶场(第十三期-php反序列化)
  • 【读论文】U-Net: Convolutional Networks for Biomedical Image Segmentation 卷积神经网络
  • 如何在Unity中实现点击一个按钮跳转到哔哩哔哩
  • 大模型在创伤性脑出血全周期预测与诊疗方案中的应用研究
  • python打卡day47
  • spring:继承接口FactoryBean获取bean实例
  • Vue速查手册
  • Unity | AmplifyShaderEditor插件基础(第五集:简易膨胀shader)
  • GOOUUU ESP32-S3-CAM 果云科技开发板开发指南(一)(超详细!)Vscode+espidf 通过摄像头拍摄照片并存取到SD卡中,文末附源码
  • SMC自修改代码一
  • JUC 串讲