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

【使用两个队列实现栈】


文章目录

  • 前言
  • 使用两个队列实现栈
    • 1.队列接口函数引入
    • 2.栈的初始化
    • 3.向栈中插入元素
    • 4.出栈操作
    • 5.取出栈顶元素
    • 6.判断栈是否为空
    • 7.释放内存空间
  • 总结


前言

本文章主要介绍栈和队列的相互转换。


使用两个队列实现栈

我们知道,栈的特点是后进先出,而队列的特点是先进先出。

栈的特点:
在这里插入图片描述
队列的特点:
在这里插入图片描述
使用两个队列实现栈的思路是:

1.向两个队列中的任一队列放入元素
2.取出元素时,队列的功能是先进先出,要达到后进先出,需要将前面的所有元素取出,存入另一个空队列中,然后将剩下的最后一个元素释放掉即可。

比如:
在这里插入图片描述
后面如果想继续插入元素的话,应该将插入的元素放在非空队列中,这样就实现了栈的功能。

在这里插入图片描述

这样实现的原因是,两个队列中必有其中一个队列是空队列,保证了栈的后进先出的特点。

下面给出一道题目
两个队列实现栈
在这里插入图片描述
这里我用c语言来实现,所以先先写好队列的基本功能,再将接口函数引入。

1.队列接口函数引入

typedef int QDataType;
typedef struct QueueNode
{QDataType data;struct QueueNode* next;
}QNode;typedef struct Queue
{QNode* head;QNode* tail;int size;
}Queue;void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);
void QueuePush(Queue* pq, QDataType x);
void QueuePop(Queue* pq);
QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);
bool QueueEmpty(Queue* pq);
int QueueSize(Queue* pq);
void QueueInit(Queue* pq)
{assert(pq);pq->head = NULL;pq->tail = NULL;pq->size = 0;
}void QueueDestroy(Queue* pq)
{assert(pq);QNode* cur = pq->head;while (cur){QNode* del = cur;cur = cur->next;free(del);//del = NULL;}pq->head = pq->tail = 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->data = x;newnode->next = NULL;if (pq->tail == NULL){pq->head = pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}pq->size++;
}void QueuePop(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));if (pq->head->next == NULL){free(pq->head);pq->head = pq->tail = NULL;}else{QNode* del = pq->head;pq->head = pq->head->next;free(del);}pq->size--;
}QDataType QueueFront(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->head->data;
}QDataType QueueBack(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->tail->data;
}bool QueueEmpty(Queue* pq)
{assert(pq);return pq->head == NULL && pq->tail == NULL;
}// 1G = 1024MB
// 1024MB = 1024*1024KB
// 1024*1024KB = 1024*1024*1024Byteint QueueSize(Queue* pq)
{assert(pq);/*int size = 0;QNode* cur = pq->head;while (cur){cur = cur->next;++size;}return size;*/return pq->size;
}

2.栈的初始化

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

栈的初始化就是将两个队列进行初始化。

3.向栈中插入元素

保证其中一个队列不为空
//首先需要判断哪个队列为空,可以用ifelse来判断,但是这样操作冗余的,所以可以使用假设
int myStackPop(MyStack*
void myStackPush(MyStack* obj, int x) {if(!QueueEmpty(&obj->q1)){QueuePush(&obj->q1,x);}else{QueuePush(&obj->q2,x);}
}

由于无法得知哪一个队列为空,则需要判断或者假设,使用判断的化,代码比较冗余,在这里我使用假设,假设第一个队列是空。

4.出栈操作

int myStackPop(MyStack* obj) {Queue*EmptyQ = &obj->q1;Queue*NonEmptyQ = &obj->q2;if(!QueueEmpty(&obj->q1)){//如果q1不为空,返回假,!就返回真,进入if//意思就是我们假设错误了。EmptyQ = &obj->q2;NonEmptyQ = &obj->q1;}//来到这里已经知道哪个是空了,把所有元素导入非空队列,将最后一个不导while(QueueSize(NonEmptyQ)>1){QueuePush(EmptyQ,QueueFront(NonEmptyQ));QueuePop(NonEmptyQ);}int top = QueueFront(NonEmptyQ);QueuePop(NonEmptyQ);return top;}

5.取出栈顶元素

int myStackTop(MyStack* obj) {//取出栈顶元素//在首先的队列中,我们虽然不能删除队尾元素,但是我们可以取出队尾的元素if(!QueueEmpty(&obj->q1)){return QueueBack(&obj->q1);}else{return QueueBack(&obj->q2);}
}

6.判断栈是否为空

bool myStackEmpty(MyStack* obj) 
{   //判断栈是否为空,需要判断两个队列是否为空return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}

判断栈是否为空,需要判断两个队列是否为空

7.释放内存空间

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

注意,由于两个队列的维护是依靠指针,所以两个队列申请的空间先释放,再释放栈结构体空间


总结

本文章介绍了两个队列实现栈的方法。
使用队列实现栈和使用栈实现队列都是可以的
下篇文章介绍使用两个栈实现队列

相关文章:

【使用两个队列实现栈】

文章目录前言使用两个队列实现栈1.队列接口函数引入2.栈的初始化3.向栈中插入元素4.出栈操作5.取出栈顶元素6.判断栈是否为空7.释放内存空间总结前言 本文章主要介绍栈和队列的相互转换。 使用两个队列实现栈 我们知道,栈的特点是后进先出,而队列的特点…...

毕业设计 基于51单片机环境监测设计 光照 PM2.5粉尘 温湿度 2.4G无线通信

基于51单片机环境监测设计 光照 PM2.5粉尘 温湿度 2.4G无线通信1、项目简介1.1 系统构成1.2 系统功能2、部分电路设计2.1 STC89C52单片机核心系统电路设计2.2 dht11温湿度检测电路设计2.3 NRF24L01无线通信电路设计3、部分代码展示3.1 NRF24L01初始化3.2 NRF24L01的SPI写时序3.…...

PowerShell Install Rabbitmq

Rabbitmq 前言 RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。RabbitMQ服务器是用Erlang语言编写的,而集群和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有与代…...

ASM 字节码插桩:隐私合规方法检测!

1.前言近两年来工信部对于应用的隐私合规安全问题愈加重视,对 Android 平台的管控程度也要比 IOS 平台严格很多,很多不合规的应用也先后被下架要求整改。笔者就曾遇到过加班整改隐私合规的问题,隐私合规问题主要针对两个方面。在用户同意隐私…...

spring data jpa使用流式查询

思路 调用org.hibernate.query.Query.stream方法查询数据 代码样例 import static org.hibernate.annotations.QueryHints.READ_ONLY; import static org.hibernate.jpa.QueryHints.HINT_FETCH_SIZE; import org.hibernate.query.Query;使用HQL查询 Query<MyEntity> …...

Golang实现RabbitMQ中死信队列各个情况

下面这段教程针对是你已经有一些基本的MQ的知识&#xff0c;比如说能够很清楚的理解queue、exchange等概念&#xff0c;如果你还不是很理解&#xff0c;我建议你先访问官网查看基本的教程。 文章目录1、造成死信队列的主要原因2、操作逻辑图3、代码实战3.1 针对原因1&#xff1…...

react源码分析:组件的创建和更新

这一章节就来讲讲ReactDOM.render()方法的内部实现与流程吧。 因为初始化的源码文件部分所涵盖的内容很多&#xff0c;包括创建渲染、更新渲染、Fiber树的创建与diff&#xff0c;element的创建与插入&#xff0c;还包括一些优化算法&#xff0c;所以我就整个的React执行流程画了…...

Android Lmkd 低内存终止守护程序

一、低内存终止守护程序 Android 低内存终止守护程序 (lmkd) 进程可监控运行中的 Android 系统的内存状态&#xff0c;并通过终止最不必要的进程来应对内存压力大的问题&#xff0c;使系统以可接受的性能水平运行。 所有应用进程都是从zygote孵化出来的&#xff0c;记录在AMS…...

快速掌握 Flutter 图片开发核心技能

大家好&#xff0c;我是 17。 在 Flutter 中使用图片是最基础能力之一。17 做了精心准备&#xff0c;满满的都是干货&#xff01;本文介绍如何在 Flutter 中使用图片&#xff0c;尽量详细&#xff0c;示例完整&#xff0c;包会&#xff01; 使用网络图片 使用网络图片超级简…...

复习使用git(二)

删除远程分支 git push origin --delete 分支名 撤销修改 撤销工作区的修改 已修改&#xff0c;但尚未添加&#xff08;add&#xff09;&#xff0c;使用 git restore 文件名 撤销工作区的修改。 Note: “git checkout – 文件名”&#xff0c;checkout 检出的意思&#x…...

魔兽世界335服务端架设对外网开放的步骤

警告&#xff1a;在没有网络安全防护措施或基础知识的情况下&#xff0c;开放端口可能造成被黑客入侵、流量攻击、破坏数据、资料泄露等情况的发生。在你选择开放端口时&#xff0c;视为已经充分了解可能发生的后果、危害&#xff0c;清楚自己在做什么&#xff0c;并且自己将对…...

华为OD机试模拟题 用 C++ 实现 - 通信误码(2023.Q1)

最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 最多获得的短信条数(2023.Q1)) 文章目录 最近更新的博客使用说明通信误码题目输入输出示例一输入输出说明示例二输入输出说明Code使用说明 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,...

Vue 核心

文章目录Vue 核心一&#xff0c;Vue 简介&#xff08;一&#xff09;官网&#xff08;二&#xff09;介绍与描述&#xff08;三&#xff09;Vue 的特点&#xff08;四&#xff09;与其它 JS 框架的关联&#xff08;五&#xff09;Vue 周边库二&#xff0c;初识 Vue三&#xff0…...

Kylin V10桌面版arm3568 源码安装redis

上传redis-5.0.14.tar.gz到/home/kylin/下载&#xff1b;解压kylinkylin:~/下载$ tar -zxvf redis-5.0.14.tar.gz/opt下新建redis目录&#xff0c;并将上面解压的文件夹移到此处kylinkylin:~/下载$ sudo mv redis-5.0.14 /opt/redis/编译&#xff1a;kylinkylin:/opt/redis/red…...

【ICCV2022】 CAPAO:一种高效的单阶段人体姿态估计模型

CAPAO&#xff1a;一种高效的单阶段人体姿态估计模型 重新思考关键点表示&#xff1a;将关键点和姿态建模作为多人姿态估计的对象&#xff08;Rethinking Keypoint Representations: Modeling Keypoints and Poses as Objects for Multi-Person Human Pose Estimation&#xf…...

ROS1学习笔记:ROS中的坐标管理系统(ubuntu20.04)

参考B站古月居ROS入门21讲&#xff1a;ROS中的坐标系管理系统 基于VMware Ubuntu 20.04 Noetic版本的环境 文章目录一、机器人中的坐标变换二、TF功能包三、小海龟跟随实验3.1 启动实验3.2 查看当前的TF树3.3 坐标相对位置可视化3.3.1 tf_echo3.3.2 rviz一、机器人中的坐标变换…...

requests---(2)session简介与自动写博客

目录&#xff1a;导读 session简介 session登录 自动写博客 获取登录cookies 抓取写博客接口 requests自动写博客 写在最后 http协议是无状态的&#xff0c;也就是每个请求都是独立的。那么登录后的一系列动作&#xff0c;都需要用cookie来验证身份是否是登录状态&#…...

基于 HAProxy + Keepalived 搭建 RabbitMQ 高可用集群

RabbitMQ 集群 通常情况下&#xff0c;在集群中我们把每一个服务称之为一个节点&#xff0c;在 RabbitMQ 集群中&#xff0c;节点类型可以分为两种&#xff1a; 内存节点&#xff1a;元数据存放于内存中。为了重启后能同步数据&#xff0c;内存节点会将磁盘节点的地址存放于磁…...

基于51单片机和proteus的智能调速风扇设计

此智能风扇是基于51单片机和proteus的仿真设计&#xff0c;功能如下&#xff1a; 1. Timer0 PWM控制电机转速 2. DHT11采集温湿度 3. LCD1602显示温湿度及电机状态 4. 按键控制电机加减速启停等 5. 串口控制电机加减速启停等 功能框图如下&#xff1a; Proteus仿真界面如下…...

SQL Server开启CDC的完整操作过程

这里写自定义目录标题写在前面SQL Server开启CDC1. 将指定库的实例先开启CDC2. 开启需要开启CDC的表3. 关闭CDC功能更详细信息参照官网写在前面 鉴于老旧数据的结构和项目都在sqlserver上存储&#xff0c;且迁移成本巨大&#xff0c;当下要为sqlserver的存储过程减负。要将一部…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

Yolov8 目标检测蒸馏学习记录

yolov8系列模型蒸馏基本流程&#xff0c;代码下载&#xff1a;这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中&#xff0c;**知识蒸馏&#xff08;Knowledge Distillation&#xff09;**被广泛应用&#xff0c;作为提升模型…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...