【数据结构】栈与队列OJ题(用队列实现栈)(用栈实现队列)
目录
1.用队列实现栈oj题
对比
一、初始化
二、出栈
三、入栈
四、取队头元素:
2.用栈实现队列
一、定义
二、入队列
三、出队列
四、队头
五、判空
前言:如果想了解什么是栈和队列请参考上一篇文章进来一起把【数据结构】的【栈与队列】狠狠玩弄,痛快到大汗淋漓-CSDN博客
本篇不进行详细讲解栈和队列的定义
1.用队列实现栈oj题
. - 力扣(LeetCode)
在这个题目中,用两个队列实现栈,以队列的方法和知识点实现栈
对比
我们先来一个函数对比一下
这是用普通方法来实现的栈的初始化
void STInit(ST* ps)
{assert(ps);ps->arr = NULL;ps->capacity = ps->top = 0;
}
这是用队列方法实现的初始化
MyStack* MyStackCreat()
{MyStack* plt = (MyStack*)malloc(sizeof(MyStack));QueueInit(&plt->q1);QueueInit(&plt->q2);return plt;}
差异很明显,队列实现的方式明显要复杂很多,哈哈哈,这就是oj题,锻炼的是你的思维
写代码之前,我们用图解先来解析
一、初始化
首先我们要知道的是,我们用队列实现栈,要定义和初始化的是什么,用队列实现栈,实则是用队列的属性实现栈的属性,所以我们在这里要定义队列
但是为什么要定义两个队列?
题目上说了要用两个队列实现
所以我们定义队列,用结构体实现两个不同的队列。
代码:
typedef int QDataType;
typedef struct QueueNode
{QDataType data;struct QueueNode* next;
}QueueNode;
typedef struct
{QueueNode q1;QueueNode q2;}MyStack;
MyStack* MyStackCreat()
{MyStack* plt = (MyStack*)malloc(sizeof(MyStack));QueueInit(&plt->q1);QueueInit(&plt->q2);return plt;}
二、出栈
1.我们先将所有需要的数据入队列,这里要注意的是入队列的时候是队尾入,队头出,也就是FIFO(先进先出)
2.入完队列之后
我们开始模拟出栈思路,栈的属性是先进后出,队列的属性是先进先出,那么问题就来了,怎么用先进先出的两个数列实现先进后出。这个就是核心思路。
对于q1队列来说,此时q2队列是空的
既然是栈的属性先进的后出,所以就是q1的队尾先出,所以要找到q1的队尾。
那么你会说这不简单嘛?用指针不就完了?
但是哈,这里要强调,用队列的属性来实现栈的属性,使用的自然是队列的接口。而不是用库函数。
队列的基本操作有什么哪?
入队列,出队列,队列判别空,取队头,取队尾,队列有效个数,销毁
所以第一个思路就来了。
将队尾前的元素直接移动到空队列q2,这样就q1队列剩下的元素就是队尾元素。
之后如果再想出栈,再将q2的队尾前的元素移动到空队列q1,队尾元素出栈。
什么时候不能出栈了呢?直到两个队列都为空的时候
这样我们就用两个队列实现了先进后出,后进先出的栈的属性
void MystackPop(MyStack* pst)
{QueueNode* nonequ = &pst->q1;QueueNode* emtyqu = &pst->q2;if (!QueueEmpty(&pst->q2)){emtyqu = &pst->q1;}else{emtyqu = &pst->q2;}while (QueueSize(nonequ) > 1){int front = QueueFront(nonequ);QueuePush(emtyqu, front);QueuePop(nonequ);}int pop = QueueFront(nonequ);QueuePop(nonequ);return pop;
}
三、入栈
入栈操作相比于出栈先简单很多,入队列和入栈的属性其实是相同的,直接入就行了。所以体现在队列上就是先进的先入栈,所以就是队头入栈。
void MyStackpush(MyStack* pst,int x)
{if (!QueueEmpty(&pst->q1)){QueuePush(&pst->q1, x);}else{QueuePush(&pst->q2, x);}}
四、取队头元素:
取队头元素听起来很复杂,其实就是在栈里就是最后一个进入的,在队列里就是队尾
直接返回队列的队尾元素即可
int MystackTop(MyStack* pst)
{if (!QueueEmpty(&pst->q1)){return QueueBack(&pst->q1);}else{return QueueBack(&pst->q2);}
}
2.用栈实现队列
232. 用栈实现队列 - 力扣(LeetCode)
对于用栈实现队列其实扒开底层逻辑就好,也不难理解,要实现push,pop,top,empty几种接口,其实就是入栈,出栈,返回栈顶,判断是否为空。至于怎么具体实现,接下来就是详细解释
一、定义
这里要定义两个栈,我们分别命名为pop和push队列
typedef struct
{ST pushST;ST popST;
}MyQU;MyQU* MyQueueCreat()
{MyQU* pst = (MyQU*)malloc(sizeof(MyQU));STInit(&pst->pushST);STInit(&pst->popST);return pst;
}
二、入队列
两者逻辑差不多,直接入队列即可,
void MyqueuePush(MyQU* obj,int x)
{StackPush(&obj->pushST, x);
}
三、出队列
其实出队列的逻辑跟出栈的逻辑是相反的,跟上面的逻辑正好是倒过来的,底层逻辑是怎么用两个先进后出的栈实现先进先出的队列但其实方法是大相径庭的。
判断pop是否为空,为空的将push的数据全部出栈,然后入栈给pop。不会空直接出栈,相当于出队列
步骤一
过程二:
过程三:
int MyQueuePop(MyQU* obj)
{if (StackEmpty(&obj->popST)){while (&obj->pushST){StackPush(&obj->popST, StackTop(&obj->pushST));StackPop(&obj->pushST);}}int pop = StackTop(&obj->popST);StackPop(&obj->popST);return pop;}
四、队头
队列中的队头限速是先进的那个元素,在栈中是最后出栈的那个元素,所以我们将栈的最后元素当作队头即可
五、判空
判断队列是空的时候,相当于push和pop的栈都为空,只有两个都为空的时候才是空。
要用到的队列和栈的接口源码
队列的接口源码
#define _CRT_SECURE_NO_WARNINGS 1
#include"Queue.h"
void QueueInit(Queue* pq)
{assert(pq);pq->phead = pq->ptail = NULL;pq->size = 0;
}
// ⼊队列,队尾
void QueuePush(Queue* pq, QDataType x)
{assert(pq);//申请新节点QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));if (newnode == NULL){perror("malloc fail!");exit(1);}newnode->data = x;newnode->next = NULL;//ptail newnodeif (pq->phead == NULL){//队列为空pq->phead = pq->ptail = newnode;}else{//队列不为空pq->ptail->next = newnode;pq->ptail = pq->ptail->next;//newnode}pq->size++;
}//队列判空
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->phead == NULL && pq->ptail == NULL;
}// 出队列,队头
void QueuePop(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));//只有一个结点的情况,避免ptail变成野指针if (pq->ptail == pq->phead){free(pq->phead);pq->phead = pq->ptail = NULL;}else{//删除队头元素、QueueNode* next = pq->phead->next;free(pq->phead);pq->phead = next;}--pq->size;
}
//取队头数据
QDataType QueueFront(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->phead->data;
}//取队尾数据QU
QDataType QueueBack(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->ptail->data;
}
//队列有效元素个数
int QueueSize(Queue* pq)
{assert(pq);/*int size = 0;QueueNode* pcur = pq->phead;while (pcur){size++ ;pcur = pcur->next;}return size;*/return pq->size;
}//销毁队列
void QueueDestroy(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));QueueNode* pcur = pq->phead;while (pcur){QueueNode* next = pcur->next;free(pcur);pcur = next;}pq->phead = pq->ptail = NULL;pq->size = 0;
}
栈的接口
#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"void STInit(ST* ps)
{assert(ps);ps->arr = NULL;ps->capacity = ps->top = 0;
}void STDestroy(ST* ps)
{assert(ps);if (ps->arr)free(ps->arr);ps->arr = NULL;ps->top = ps->capacity = 0;
}void StackPush(ST* ps, STDataType x)
{assert(ps);//1.判断空间是否足够if (ps->capacity == ps->top){int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;STDataType* tmp = (STDataType*)realloc(ps->arr, newCapacity * sizeof(STDataType));if (tmp == NULL){perror("realloc fail!");exit(1);}ps->arr = tmp;ps->capacity = newCapacity;}//空间足够ps->arr[ps->top++] = x;
}
bool StackEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}
void StackPop(ST* ps)
{assert(ps);assert(!StackEmpty(ps));--ps->top;
}//取栈顶元素
STDataType StackTop(ST* ps)
{assert(ps);assert(!StackEmpty(ps));return ps->arr[ps->top - 1];
}//获取栈中有效元素个数
int STSize(ST* ps)
{assert(ps);return ps->top;
}
相关文章:

【数据结构】栈与队列OJ题(用队列实现栈)(用栈实现队列)
目录 1.用队列实现栈oj题 对比 一、初始化 二、出栈 三、入栈 四、取队头元素: 2.用栈实现队列 一、定义 二、入队列 三、出队列 四、队头 五、判空 前言:如果想了解什么是栈和队列请参考上一篇文章进来一起把【数据结构】的【栈与队列】狠…...

element-ui打包之后图标不显示,woff、ttf加载404
1、bug 起因 昨天在 vue 项目中编写 element-ui 的树形结构的表格,发现项目中无法生效,定位问题之后发现项目使用的 element-ui 的版本是 2.4.11 。看了官方最新版本是 2.15.14,然后得知 2.4.11 版本是不支持表格树形结构的。于是决定升级 el…...

探究零工市场小程序如何改变传统兼职模式
近年来,零工市场小程序正逐渐改变传统的兼职模式,为求职者和雇主提供了一个更为高效、便捷的平台。本文将深入探讨零工市场小程序如何影响传统兼职模式,以及它带来的优势和挑战。 一、背景与挑战 传统的兼职市场往往存在信息不对称的问题&am…...

MySQL数据库安装(详细)—>Mariadb的安装(day21)
该网盘链接有效期为7天,有需要评论区扣我: 通过网盘分享的文件:mariadb-10.3.7-winx64.msi 链接: https://pan.baidu.com/s/1-r_w3NuP8amhIEedmTkWsQ?pwd2ua7 提取码: 2ua7 1 双击打开安装软件 本次安装的是mariaDB,双击打开mar…...

微信小程序实践案例
参考视频: https://www.bilibili.com/video/BV1834y1676P/?p36&spm_id_frompageDriver&vd_sourceb604c19516c17da30b6b1abb6c4e7ec0 前期准备 1、新建三个页面 "pages": ["pages/home/home","pages/message/message",&quo…...

DataLoader使用
文章目录 一、认识dataloader二、DataLoader整合数据集三、使用DataLoader展示图片方法四、去除结尾不满足batch_size设值图片的展示 一、认识dataloader DataLoader 用于封装数据集,并提供批量加载数据的迭代器。它支持自动打乱数据、多线程数据加载等功能。datas…...
CSS学习11--版心和布局流程以及几种分布的例子
版心和布局流程 一、版心二、布局流程三、一列固定宽度且居中四、两列左窄右宽五、通栏平均分布型 一、版心 版心:是指网页主题内容所在的区域。一般在浏览器窗口水平居中位置,常见的宽度值为960px、980px、1000px、1200px等。 二、布局流程 为了提高…...

NetSuite AI 图生代码
去年的ChatGPT热潮期间,我们写过一篇文章说GTP辅助编程的事。 NetSuite GPT的辅助编程实践_如何打开netsuite: html script notes的视图-CSDN博客文章浏览阅读2.2k次,点赞4次,收藏3次。作为GPT综合症的一种表现,我们今朝来探究下…...
Java - BigDecimal计算中位数
日常开发中,如果使用数据库来直接查询一组数据的中位数,就比较简单,直接使用对应的函数就可以了,例如: SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(目标列名 ORDER BY 目标列名),,,Count(1)/2),,,-1) AS 目标列名_…...

Tensorflow2如何读取自制数据集并训练模型?-- Tensorflow自学笔记13
一. 如何自制数据集? 1. 目录结构 以下是自制数据集-手写数字集, 保存在目录 mnist_image_label 下 2. 数据存储格式 2.1. 目录mnist_train_jpeg_60000 下存放的是 60000张用于测试的手写数字 如 : 0_5.jpg, 表示编号为0,标签为5的图片 6_1.jpg, 表示…...

JVM系列(七) -对象的内存分配流程
一、摘要 在之前的文章中,我们介绍了类加载的过程、JVM 内存布局和对象的创建过程相关的知识。 本篇综合之前的知识,重点介绍一下对象的内存分配流程。 二、对象的内存分配原则 在之前的 JVM 内存结构布局的文章中,我们介绍到了 Java 堆的内存布局,由 年轻代 (Young Ge…...
Apache Ignite 在处理大规模数据时有哪些优势和局限性?
Apache Ignite 在处理大规模数据时的优势和局限性可以从以下几个方面进行分析: 优势 高性能:Ignite 利用内存计算的优势,实现了极高的读写性能,通过分布式架构,它可以将数据分散到多个节点上,从而实现了并…...

怎么利用NodeJS发送视频短信
随着5G时代的来临,企业的数字化转型步伐日益加快,视频短信作为新兴的数字营销工具,正逐步展现出其大的潜力。视频群发短信以其独特的形式和内容,将图片、文字、视频、声音融为一体,为用户带来全新的直观感受࿰…...

WebAPI(三)、 DOM 日期对象Date;获取事件戳;根据节点关系查找节点
文章目录 DOM1. 日期对象(1)、日期对象方法(2)、时间戳(3)、下课倒计时 2. 节点操作(1)、 查找节点(根据节点关系找)(2)、 增加节点:创建create、追加append、克隆clone(3)、 删除节点remove DOM 1. 日期对象 日期对象就是用来表示时间的对…...

012.Oracle-索引
我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈 入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈 虚 拟 环 境 搭 建 :👉&…...
SSL 证书 | 免费获取与自动续期全攻略
前言 随着互联网的不断发展,网站的安全性越来越受到人们的关注。 SSL证书 作为一种保障网站安全的重要手段,已经成为了许多网站的必备配置。 以前阿里云每个账号能生成二十个期限 1 年的免费 SSL 证书,一直用,还挺香࿰…...
达梦数据库管理员常用SQL(一)
达梦数据库管理员常用SQL(一) 数据库基本信息数据库参数信息表空间信息日志文件信息进程和线程信息会话连接信息SQL执行信息等待事件信息事务和锁信息数据库基本信息 --查询数据库内部版本号 select id_code; select build_version from v$instance; select * from v$versi…...
HttpUtils工具类(三)OKHttpClient使用详细教程
OkHttpClient 是一个由 Square 公司开发的 HTTP 客户端库,用于在 Android 和 Java 应用中进行网络请求。它支持同步和异步请求、连接池、超时设置、拦截器等功能,适合用于高性能网络请求,特别是在需要处理复杂的网络操作时。 一、OKHttpClien…...

重生奇迹MU老大哥剑士职业宝刀未老
重生奇迹MU中,老大哥剑士职业一直以来备受玩家们的喜爱。这个职业不仅拥有强大的攻击力、防御力和战斗技巧,而且还能够通过使用各种宝刀来增强自身的战斗能力。即便经过了多年的沉淀,老大哥剑士依然是一名宝刀未老的男人,仍然能够…...
关于Netty详细介绍,Netty原理架构解析
Netty 是什么 1)Netty 是 JBoss 开源项目,是异步的、基于事件驱动的网络应用框架,它以高性能、高并发著称。所谓基于事件驱动,说得简单点就是 Netty 会根据客户端事件(连接、读、写等)做出响应,…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...

LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...