【leetcode】225.用队列实现栈

news2025/1/26 15:40:37

分析:

队列遵循先入先出的原则,栈遵循后入先出的原则

也就是说,使用队列实现栈时,入队操作正常,但是出队要模拟出栈的操作,我们需要访问的是队尾的元素;题目允许使用两个队列,我们可以先将存有数据的队列中除队尾元素外的所有元素依次出队,存入空队列中,再访问原队列中的队头元素即可

1.使用两个队列构造栈:

C语言中没有定义队列的结构,我们需要自定义队列及其相关操作

如下:结构MyStack由两个队列结构q1和q2构成

为我们创建的栈结构进行动态内存申请并进行初始化

//由两个队列构成栈结构
typedef struct {
    Queue q1;
    Queue q2;

} MyStack;
//创建栈
MyStack* myStackCreate() {
    //myStack未具有两个队列的栈结构类型
    MyStack* obj = (MyStack*)malloc(sizeof(MyStack));
		//内存开辟失败
		if(obj == NULL)
		{
			perror("malloc fail");
			exit(-1);
		}
		//开辟成功,初始化
		else
		{
			QueueInit(&obj->q1);
			QueueInit(&obj->q2);
		}
    return obj;
}
2.压栈操作

模拟栈的压栈操作,数据正常入队即可

📖Note:

我们要将数据插入非空的队列,保证每次都存在一个空队列可以进行数据的存储

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

}
3.移除并返回栈顶元素

模拟栈的出栈操作:访问并移除的是非空队列的队尾元素

步骤:将存有数据的队列中除队尾元素外的所有元素依次出队,存入空队列中,再访问并移除原队列中的队头元素即可,如下图:

上述操作后,q1和q2的结构如下:

此时,将队列q1中的元素(相当于后入的栈顶元素)先存储,再出队列q1(即清空队列q1,供下次压栈操作使用),返回存储的值即可

int myStackPop(MyStack* obj) {
    Queue* empty = &obj->q1;
    Queue* nonempty = &obj->q2;
		if(!QueueEmpty(&obj->q1))
		{
				nonempty = &obj->q1;	
				empty = &obj->q2;	
		}
		//非空队列前n-1个入空队列并出队,剩下最后一个即为栈顶元素
		while(QueueSize(nonempty) > 1)
		{
				QueuePush(empty,QueueFront(nonempty));
				QueuePop(nonempty);
		}
		int top = QueueFront(nonempty);
		QueuePop(nonempty);//清空队列
		return top;
}

4.返回栈顶元素

栈顶元素即非空队列的队尾数据

int myStackTop(MyStack* obj) { 
    if(!QueueEmpty(&obj->q1))
    {
        return QueueBack(&obj->q1);
    }
    else
    {
        return QueueBack(&obj->q2);
    }
}
5.判断是否为空栈 

myStack是由两个队列构成的栈结构,当两个队列都为空时栈即为空

bool myStackEmpty(MyStack* obj) {

    return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}

6.空间释放

创建栈时为其动态申请了空间,操作结束需要进行空间释放,否则会造成内存泄漏

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

 完整参考代码如下:

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>

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

typedef struct Queue
{
	QNode* head;
	QNode* tail;
}Queue;

#define bool int
#define true 1
#define false 0


//队列初始化
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 = pq->tail = NULL;
}
//队列销毁
void QueueDestroy(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->head;
	while (cur)
	{
		QNode* del = cur;
		cur = cur->next;
		free(del);
	}
	pq->head = pq->tail = NULL;
}
//数据入队
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	else
	{
		newnode->data = x;
		newnode->next = NULL;
	}
	//空队列时插入
	if (pq->tail == NULL)
	{
		pq->head = pq->tail = newnode;
	}
	//非空队列时插入
	else
	{
		pq->tail->next = newnode;//链接新元素
		pq->tail = newnode;//更新队尾
	}
}
//数据出队
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);
		del = 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;
}
//判断队列是否为空
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	/*if (pq->tail == pq->head == NULL)
	{
		return true;
	}
	else
	{
		return false;
	}*/
	return pq->head == NULL && pq->tail == NULL;
}
//求队列的大小
int QueueSize(Queue* pq)
{
	assert(pq);
	int size = 0;
	QNode* cur = pq->head;
	while (cur)
	{
		size++;
		cur = cur->next;
	}
	return size;
}

//由两个队列构成栈结构
typedef struct {
    Queue q1;
    Queue q2;

} MyStack;
//创建栈
MyStack* myStackCreate() {
    //myStack未具有两个队列的栈结构类型
    MyStack* obj = (MyStack*)malloc(sizeof(MyStack));
		//内存开辟失败
		if(obj == NULL)
		{
			perror("malloc fail");
			exit(-1);
		}
		//开辟成功,初始化
		else
		{
			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))
		{
				nonempty = &obj->q1;	
				empty = &obj->q2;	
		}
		//非空队列前n-1个入空队列并出队,剩下最后一个即为栈顶元素
		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) {
    QueueDestroy(&obj->q1);
    QueueDestroy(&obj->q2);
}

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

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

相关文章

ardupilot开发 --- 位置控制篇

几个疑问 如何根据GPS定位信息进行位置控制&#xff1f; 经纬度海拔高度如何转成导航坐标系&#xff1f; 飞控中的航迹点waypoint是基于那个坐标系的点&#xff1f;导航坐标系&#xff1f; Home点&#xff1f;导航坐标系的原点&#xff1f;电机解锁时的点&#xff1f;xyz&…

JTS多边形自相交异常问题处理

遇到一个奇怪的问题&#xff0c;线上某户型导入报了个异常com.vividsolutions.jts.geom.TopologyException: found non-noded intersection between LINESTRING。 看日志定位问题出在计算两柜体是否相交的方法上 Point middlePoint AlgorithmUtils.middlePoint(sp,ep); Poin…

thinkphp6前后端验证码分离以及验证

1.验证码接口生成验证码: public function verify(){return captcha(); } 也可以自己写方法 2.验证方法和普通模式session验证有区别,需要改原文件: 修改后的代码: <?php // +---------------------------------------------------------------------- // | ThinkP…

360浏览器打开CSDN多个写文章窗口(文章编辑窗口、文章编辑标签)时,文章内容消失问题解决办法(取消勾选“阻止不同源页面共享Cookie”)

文章目录 快速解决办法解决360浏览器打开CSDN多个写文章窗口时&#xff0c;文章内容消失问题的策略目录问题描述理解CookiesCookie和同源策略的关联阻止不同源页面共享Cookie的影响解决策略总结 快速解决办法 点击浏览器设置&#xff1a; 点击高级设置–>网页内容高级设置…

【算法】双指针划分思想妙解移动零

Problem: 283. 移动零 文章目录 思路算法图解分析复杂度Code 思路 首先我们来讲一下本题的思路 本题主要可以归到【数组划分/数组分块】这一类的题型。我们将一个数组中的所有元素划分为两段区间&#xff0c;左侧是非零元素&#xff0c;右侧是零元素 那解决这一类的题我们首先想…

气象知识丨自动气象站的基本信息介绍

自动气象站的基本概述&#xff1a;自动气象站可以用于对大气温度、相对湿度、风向、风速、雨量、气压、太阳辐射、土壤温度、土壤湿度、能见度等众多气象要素进行全天候现场监测&#xff0c;具有气象信息服务功能&#xff0c;可以通过多种通讯方法与监控平台进行通讯&#xff0…

PyTorch学习笔记(十四)——网络模型的保存与读取

两种方式保存和加载模型 方式一 保存模型 不仅保存了网络模型的结构&#xff0c;也保存了网络模型的参数 import torch import torchvisionvgg16 torchvision.models.vgg16(weightsFalse) torch.save(vgg16,"vgg16_method1.pth") 加载模型 打印出的是网络模型的…

C++新经典05--文件操作

文件简介 文件在程序设计中是一个比较重要的概念&#xff0c;这里所说的文件&#xff0c;是指保存在硬盘、U盘等存储介质上的数据&#xff0c;这些存储介质&#xff08;简称磁盘&#xff09;上的数据就是以一个个文件的形式体现&#xff0c;每一个文件有一个对应的名字&#x…

描述性统计:集中趋势和分散

一、说明 在本文中&#xff0c;我们将深入研究描述性统计领域&#xff0c;探索其不同方面&#xff0c;包括统计类型、总体与样本、参数与统计、数据类型以及集中趋势和离散的度量。 让我幽默地向您介绍统计数据。 “统计数据就像比基尼。他们揭示的东西是暗示性的&#xff0c;但…

API开放!将语聚AI智能助手接入到您的自有系统中

概述 语聚AI基于集简云强大的应用软件“连接器”能力&#xff0c;提供了工具延展、知识延展、模型延展和嵌入集成等一系列功能&#xff0c;为用户带来了更加强大和智能的AI新体验。 我们深知&#xff0c;每家企业对于AI应用都有自己独特的需求和应用场景&#xff0c;只有通过开…

接口测试之Postman 安装与使用

Postman 安装 官网下载地址 www.postman.com/downloads Postman 使用 发送get请求 新建请求 填写请求方式&#xff1a;GET 填写请求 URL&#xff1a; ceshiren.com/ httpbin.ceshiren.com/get 填写请求参数&#xff1a; para_key para_value 发送 POST 请求 请求方式&a…

2023年的IC求职究竟有多难?

去年应移知教育要求&#xff0c;写了一篇关于秋招的看法《聊一聊今年的芯片就业市场》&#xff0c;当时提出来的点很简单&#xff1a; ● 处在赛道内的人要正视竞争的难度&#xff0c;提升自身的企业价值分&#xff1b; ● 想要进入赛道的人要放平心态&#xff0c;降低和保留…

C++ string类的模拟实现

模拟实现string类不是为了造一个更好的轮子&#xff0c;而是更加理解string类&#xff0c;从而来掌握string类的使用 string类的接口设计繁多&#xff0c;故而不会全部涵盖到&#xff0c;但是核心的会模拟实现 库中string类是封装在std的命名空间中的&#xff0c;所以在模拟…

ImageKit10 VCL Crack

ImageKit10 VCL Crack ImageKit10 VCL是一个允许您快速轻松地将图像处理功能添加到应用程序中的组件。使用ImageKit10 VCL&#xff0c;您可以编写从TWAIN扫描仪和数码相机检索图像的应用程序;加载和保存图像文件&#xff0c;并将图像从一种格式转换为另一种格式;编辑图像、在图…

MySQL的Json类型字段IN查询分组和优化方法

前言 MySQL从5.7的版本开始支持Json后&#xff0c;我时常在设计表格时习惯性地添加一个Json类型字段&#xff0c;用做列的冗余。毕竟Json的非结构性&#xff0c;存储数据更灵活&#xff0c;比如接口请求记录用于存储请求参数&#xff0c;因为每个接口入参不一致&#xff0c;也…

python的交互式库Qgrid

目录 Qgrid介绍Qgrid使用Qgrid使用过程中遇到的问题解决方案 Qgrid介绍 在Jupyter notebook中直接读取DataFrame数据&#xff0c;只显示为静态表格的形式&#xff0c;没有类似于excel的筛选等交互式功能。Qgrid作为 Jupyter notebook 组件&#xff0c;可以为我们的 DataFrame …

三本书与三场发布会,和鲸社区重新定义编程类书籍从阅读到实践新体验

当 AI 开发者社区配备 AI 基础设施开发平台工具时&#xff0c;它还能做什么&#xff1f; 答案是&#xff1a;过去半年&#xff0c;和鲸社区凭借在气象、医学、社科等垂直领域的长期积累以及多方伙伴的支持&#xff0c;联合举办了三场新书发布会——从 Python 到 R 语言 、从气…

程序员与ChatGPT的交织:探索人工智能和软件开发的新篇章

目录 前言创作者程序员会被替代吗程序员如何更好的使用chatgpt 前言 在技术持续进步的当今世界&#xff0c;程序员与人工智能&#xff08;AI&#xff09;之间的关系越来越紧密。特别是对于一些创新性的技术如OpenAI旗下的ChatGPT&#xff0c;这种联系就更为明显。程序员与Chat…

2023/8/16 华为云OCR识别驾驶证、行驶证

目录 一、 注册华为云账号开通识别驾驶证、行驶证服务 二、编写配置文件 2.1、配置秘钥 2.2、 编写配置工具类 三、接口测试 3.1、测试接口 3.2、结果 四、实际工作中遇到的问题 4.1、前端传值问题 4.2、后端获取数据问题 4.3、使用openfeign调用接口报错 4.3、前端显示问题…

python bytes基本用法

目录 1 第一个字符变大写&#xff0c;其余字符变小写 capitalize() 2 生成指定长度内容&#xff0c;然后把指定的bytes放到中间 center() 3 计数 count() 4 解码 decode() 5 是否以指定的内容结尾 endswith() 6 将制表符调整到指定大小 expandtabs() 7 寻找指…