每日一题——用两个队列实现栈

news2024/11/26 20:44:11

每日一题

用两个队列实现栈

题目链接

在这里插入图片描述

思路

  • 这里主要讲怎么实现出栈StackPop操作
  • 做完用两个栈实现队列,我们可能会想当然的认为,这一题也是一个主队列,一个辅助队列,当要出队时,首先判断辅助队列是否为空,如果是,那么就像《两个栈实现队列》一样,将主队列的所有元素逆序放入辅助队列中,但这种方法是行不通的,因为队列的原则是先进先出,元素只能从队尾入,从队头出,因此我们不能逆序弹出队列元素,只能按原来顺序弹出。
  • 因此,我们就要改变辅助队列的用法
    • 由于栈的性质是先入后出,队列的性质是先入先出,因此,如果要用队列来实现栈,那么如果要对这个栈进行出队操作,那么弹出的元素就应该是队列里的最后一个元素
    • 所以,当要实现出栈时,我们可以先将主队列中除最后一个元素的所有元素全都放入辅助队列中,这时,主队列就只剩一个元素(即最后一个元素)了,我们将这个元素进行出队操作,即实现了出栈
    • 最后,再将辅助队列的元素重新移回主队列,方便后续操作。

实现代码

/*********************队列基本功能实现*************************/
typedef int QDataType;

typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType data;
}QueueNode;

typedef struct Queue	//定义存放指向队头,队尾指针的结构体
{
	QueueNode* head;	//指向队头
	QueueNode* tail;	//指向队尾
}Queue;

//初始化
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = NULL;
	pq->tail = NULL;
}

//销毁
void QueueDestroy(Queue* pq)
{
	QueueNode* cur = pq->head;	//定义临时变量
	while (cur)
	{
		pq->head = pq->head->next;	//链表下滑
		free(cur);		//释放空间
		cur = pq->head;	//更新临时变量
	}
	pq->tail = NULL;	//空间释放完毕后head已经为空,但tail成为了野指针,所以要置空
}

//判空
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->head == NULL;
}

//入队
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));		//创建新节点
	newnode->data = x;
	newnode->next = NULL;
	if (pq->tail == NULL && pq->head == NULL)	//如果队列为空
	{
		pq->head = newnode;	//使队头、队尾指针同时指向新节点
		pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;	//使队尾指针的指向下一个节点的指针指向新节点
		pq->tail = newnode;	//更新队尾指针
	}
}

//出队
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));	//队列不能为空
	QueueNode* cur = pq->head;	//定义临时变量保存队头指针
	pq->head = pq->head->next;	//使队头指针指向下一个节点
	free(cur);		//释放原来的队头
	if (pq->head == NULL)
		pq->tail = NULL;	//如果节点已经全部出队,则要将队尾指针置空,防止形成野指针
}

//返回队头元素
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;
}

//返回队列大小
int QueueSize(Queue* pq)
{
	QueueNode* cur = pq->head;
	int size = 0;
	while (cur)
	{
		size++;
		cur = cur->next;
	}
	return size;
}

/***********************用两个队列实现栈**************************/

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


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

void myStackPush(MyStack* obj, int x) {
	QueuePush(obj->q1, x);
}

int myStackPop(MyStack* obj) {
	int size = QueueSize(obj->q1);
    //将除最后一个队列元素的其他所有元素放入辅助队列中
	while (--size)
	{
		QueuePush(obj->q2, QueueFront(obj->q1));
		QueuePop(obj->q1);
	}
    //保存要弹出的值
	int result = QueueFront(obj->q1);
    //出队
	QueuePop(obj->q1);
    
	size = QueueSize(obj->q2);
    //将辅助队列的元素重新移回主队列中
	while (size--)
	{
		QueuePush(obj->q1, QueueFront(obj->q2));
		QueuePop(obj->q2);
	}
	return result;
}

int myStackTop(MyStack* obj) {
	return QueueBack(obj->q1);
}

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

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

/**
 * 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.coloradmin.cn/o/573580.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码线程安全

线程生命周期 synchronized synchronized会自动释放锁 synchronized同步代码块 synchronized后面括号里obj是锁对象(保证唯一);static修饰的obj对象是自定义MyThread线程类的静态成员变量,该自定义线程类所有实例共享保证锁对象唯一性;另一…

广度优先搜索

注:最近有些事所以请大家原谅 那么废话讲完了┏ (゜ω゜)☞ 目录 一:认识广搜 广度优先搜索算法的搜索步骤一般是: 二:导入 广度优先搜索一般可以回答两类问题: 三:基础应用 例题1:寻宝…

Electron 入门案例详解

目录 前言一、开发环境检查二、入门案例实现1.初始化项目2.安装electron包3.运行electron应用 三、创建第一个应用窗口1.准备页面2.创建窗口3.运行窗口 总结 前言 Electron 是一种基于 Node.js 和 Chromium 的框架,可以方便地创建跨平台的桌面应用程序。虽然 Elect…

jlink-v8刷固件及解决keil报错 j-link is defective,j-link clone

今天在调试STM32F407的程序时,下载程序时突然keil识别不到jlink了,还以为是驱动的问题,重新装了好几次驱动,结果还是不行,于是就网上找各种办法,最后决定重新刷固件。网上的方法很多,好多都失败…

Kotlin Compose Multiplatform 跨平台(Android端、桌面端)开发实践之使用 SQLDelight 将数据储存至数据库

前言 关于标题和文章主题 取标题的时候我还在想,我应该写 Compose 跨平台呢还是写 Kotlin 跨平台。 毕竟对于我的整体项目而言,确实是 Compose 跨平台开发,但是对于我这篇文章要说的东西,那其实也涉及不到多少 Compose 相关的内…

力扣sql中等篇练习(二十七)

力扣sql中等篇练习(二十七) 1 连续两年有3个及以上订单的产品 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 # Write your MySQL query statement below WITH T as (SELECT t.product_id,t.d,count(order_id) numFROM(SELECT order_id,product_id,…

es elasticsearch 九 索引index 定制分词器 type结构后期弃用原因 定制动态映射 动态映射模板 零停机重建索引

目录 索引index 定制分词器 Type底层结构及弃用原因 定制 dynamic mapping 定制dynamic mapping template 动态映射模板 零停机重建索引 生产环境应该度别名数据 索引index Put /index Stings 分片 Mapping 映射 Aliases 别名 增加 Put my_index2 { "se…

网络安全行业在经济下行期仍然稳步增长,快抓住风口入行

根据IDC《2022年第四季度中国IT安全软件市场跟踪报告》的数据,2022年下半年中国IT安全软件市场厂商整体收入约为23.8亿美元(约合165.7亿元人民币),同比上升12.4%。结合全年数据,2022全年中国IT安全软件市场规模达到39.…

NodeJS 文件操作④

文章目录 ✨文章有误请指正,如果觉得对你有用,请点三连一波,蟹蟹支持😘前言NODE内置模块 FS模块 CallBack API mkdir (创建文件夹 异步) rmdir(删除文件夹 异步) rm&#…

百度爱番番的线索如何自动导入至CRM系统中?

百度爱番番是什么? 百度爱番番是应用百度强大AI能力,帮助企业实现营销数字化、自动化、智能化,为企业提供拓客、集客、管客的一站式智能解决方案,助力企业营销变得专业且智能。 百度爱番番的线索如何自动导入至CRM系统中&#xf…

MKS SERVO4257D 闭环步进电机_系列2 菜单说明

第1部分 产品介绍 MKS SERVO 28D/35D/42D/57D 系列闭环步进电机是创客基地为满足市场需求而自主研发的一款产品。具备脉冲接口和RS485/CAN串行接口,支持MODBUS-RTU通讯协议,内置高效FOC矢量算法,采用高精度编码器,通过位置反馈&am…

数据结构和算法,在Python中的实现方式

部分数据来源:ChatGPT 数据结构 在计算机科学中,数据结构指的是计算机中用来存储和组织数据的方式。数据结构是为算法服务的,同一个算法在不同的数据结构上运行效率可能会有很大的不同。这就要求我们在解决问题时要根据具体情况选择合适的数…

前端中间件Midway的使用

一、 关于midway1. 解决什么痛点2. 期望达到什么效果 二、创建应用并使用1. 创建midway应用2. 认识Midway2.1 目录结构2.2 Controller2.3 路由2.4 获取请求参数2.5 Web中间件2.6 组件使用2.7 服务(service) 三、写到最后 一、 关于midway Midway 是阿里巴巴 - 淘宝前端架构团队…

别做重复低质的工作内容摸鱼了,18k大佬分享自动化测试秘籍

自动化测试面试真题(附答案) 一、编程语法题 1、python有哪些数据类型 2、怎么将两个字典合并 3、python 如何将json写到文件里? 4、 __init__和_new__区别? 5、什么是可变、不可变类型? 6、mysql注入点,用工具对目标站直接写入…

IDEA操作数据库并设置时区

目录 设置mysql的时区的方法(提供三种选择) 1、直接在advanced上配置serverTimezone属性值(单次连接有效) 2、进入MySQL客户端修改time_zone 3、直接修改MySQL的my.ini配置文件设置time-zone 使用Database 1、查看当前数据源…

uCOSii信号量的作用

uCOSii中信号量的作用: 在创建信号量时,Sem_EventOSSemCreate(1)用于分时复用共享资源; Sem_EventOSSemCreate(0)用于中断和任务间同步或任务之间的同步。 具体在使用时,需要灵活运用。在访问共享资源时,我喜欢用互…

【计算机视觉 | 目标检测】arxiv 计算机视觉关于目标检测的学术速递(5月26日论文合集)

文章目录 一、检测相关(9篇)1.1 Energy-based Detection of Adverse Weather Effects in LiDAR Data1.2 Anomaly Detection with Conditioned Denoising Diffusion Models1.3 Mask Attack Detection Using Vascular-weighted Motion-robust rPPG Signals1.4 Improved Multi-Sca…

AccessShareLock pg cancel backend terminate backend

AccessShareLock 在PostgreSQL中,AccessShareLock是一种用于控制对数据库对象并发访问的锁类型。它是一种读锁,允许多个事务同时从同一个对象进行读取,但它阻止并发事务获取冲突的锁,比如写锁或独占锁。 当一个事务在对象上获取…

【指针的深刻理解】

如何看待下面代码中的a变量? #include<stdio.h> int main() {int a 0;//同样的一个a&#xff0c;在不同的表达式中&#xff0c;名称是一样的&#xff0c;但是含义是完全不同的&#xff01;a 10;//使用的是a的空间&#xff1a;左值int b a; //使用的是a的内容&#x…

Java jiraClient上传附件不能在浏览器预览的问题分析

最近测试的同学反馈问题说使用平台的报bug上传视频的附件以后&#xff0c;然后在jira上确没有办法通过点击附件进行预览&#xff0c;而需要下载下来才能够查看。但是如果是直接在jira上进行上传附件就不会有这个问题 如果说不了解具体原因的&#xff0c;其实就会觉得这个问题非…