LeetCode225.用队列实现栈

news2024/9/30 6:14:31

💭前言:

建议本题和LeetCode232对比实现

syseptember的个人博客:LeetCode232.栈模拟队列icon-default.png?t=N4HBhttp://t.csdn.cn/HCEDg

题目

 

 思路

❗注意:本题的逻辑结构是栈,物理结构是队列,我们需要通过2个队列模拟栈的操作。

 🔨 元素入栈:如果queue1为空就将元素插入到q1中。

 🔨元素出栈:如果queue1不为空,那么将queue1中除队尾数据全部删除并插入到queue2,再删除queue的队尾数据。

 

 

 🔨继续入栈:因为queue1为空,所以将元素插入到queue2中

 🔨继续出栈:和第一次一样,将queue2的数据除队尾全部删除插入到queue1中,最后删除queue的队尾。

 

 ❗注意:对比上述2次入栈、出栈我们可以发现---每次出栈都是将非空队列的数据导入到空队列数据,每次进栈都是将元素插入到非空队列中,所以后续在入栈、出栈函数中仅有queue1和queue2是不够的,我们还需要判断它们谁是空队列、谁是非空队列。

🔺总结

 

代码

❗注意:
①下面的pop函数复用了top函数,因为它们都需要返回栈顶元素。
②之所以队列实现一个取队尾的函数是为了在栈中取栈顶元素只需取出非空队列的队尾

💬由于作者还没有学习C++的STL库,所以只能手写一个队列:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
typedef int QDataType;
//队列由于具备先进后出的特点,使用链表实现效率更高,因为数组头插和头删的效率比链表低
typedef struct Qnode
{
	QDataType val;
	struct Qnode* next;
}Qnode;
typedef struct
{
	Qnode* head;//指向队列头
	Qnode* tail;//指向队列尾
	int size;//记录队列有效元素个数
}Queue;

//队列的初始化
extern void QueueInit(Queue* pq);
//队列为空
extern bool QueueEmpty(const Queue* pq);
//入队列
extern void QueuePush(Queue* pq, QDataType x);
//出队列
extern void QueuePop(Queue* pq);
//获取队列头部元素
extern QDataType QueueFront(const Queue* pq);
//获取队列尾部元素
extern QDataType QueueBack(const Queue* pq);
//获取队列元素个数
extern int QueueSize(const Queue* pq);
//销毁队列
extern void QueueDestroy(Queue* pq);

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

//队列是否为空
bool QueueEmpty(const Queue* pq)
{
	assert(pq);
	//return pq->head == NULL && pq->tail == NULL;
	return pq->size == 0;
}

//入队列
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	Qnode* newnode = (Qnode*)malloc(sizeof(Qnode));
	assert(newnode);
	newnode->val = x;
	newnode->next = NULL;
	//链表为空
	if (pq->tail == NULL)
	{
		assert(pq->head == 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));
	//只有1个节点
	if (pq->size == 1)
	{
		Qnode* tmp = pq->head;
		pq->head = pq->tail = NULL;
		free(tmp);
	}
	//2节点及以上
	else
	{
		//头删
		Qnode* tmp = pq->head;
		pq->head = pq->head->next;
		free(tmp);
	}
	pq->size--;
}

//获取队列头部元素
QDataType QueueFront(const Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->head->val;
}

//获取队列尾部元素
QDataType QueueBack(const Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->tail->val;
}

//获取队列元素个数
int QueueSize(const Queue* pq)
{
	assert(pq);
	return pq->size;
}

//销毁队列
void QueueDestroy(Queue* pq)
{
	assert(pq);
	Qnode* cur = pq->head;
	while (cur)
	{
		Qnode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = 0;
	pq->size = 0;
}
typedef struct {
    Queue q1;
    Queue q2;
} MyStack;


MyStack* myStackCreate() {
    MyStack* stack = (MyStack*)malloc(sizeof(MyStack));
    //初始化2个队列
    QueueInit(&stack->q1);
    QueueInit(&stack->q2);
    return stack;
}

void myStackPush(MyStack* obj, int x) {
    //将数据插入到非空队列中
    if (!QueueEmpty(&obj->q1))
    {
        QueuePush(&obj->q1, x);
    }
    else
    {
        QueuePush(&obj->q2, x);
    }
}

int myStackTop(MyStack* obj) {
    //找出非空队列和空队列
	Queue* pNonEmptyQ = &obj->q1;
	Queue* pEmptyQ = &obj->q2;
	if (!QueueEmpty(&obj->q2))
	{
		pNonEmptyQ = &obj->q2;
		pEmptyQ = &obj->q1;
	}
    //非空队列的队尾就是栈顶元素
	return QueueBack(pNonEmptyQ);
}

//pop可以复用top函数
int myStackPop(MyStack* obj) {
	//保存栈顶数据
	int ret = myStackTop(obj);
	//这里一定要定义成指向空队列的指针
	Queue* pNonEmptyQ = &obj->q1;
	Queue* pEmptyQ = &obj->q2;
	if (!QueueEmpty(&obj->q2))
	{
		pNonEmptyQ = &obj->q2;
		pEmptyQ = &obj->q1;
	}
    //非空队列像空队列导入数据
	while (QueueSize(pNonEmptyQ) > 1)
	{
		QueuePush(pEmptyQ, QueueFront(pNonEmptyQ));
		QueuePop(pNonEmptyQ);
	}
	//删除栈顶元素--也就是删除非空队列队尾
	QueuePop(pNonEmptyQ);
	return ret;
}

bool myStackEmpty(MyStack* obj) {
    //两个队列都为空栈为空
	return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}

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

 

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

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

相关文章

Doxygen源码分析:构建过程简介,并生成doxygen自身的C++文档

2023-05-19 11:52:17 ChrisZZ imzhuofoxmailcom Hompage https://github.com/zchrissirhcz 文章目录 1. doxygen 版本2. 找出所有的 CMakeLists.txt 和 *.cmake 文件3. cmake 构建目标清单4. 生成 Doxygen 自己的文档 1. doxygen 版本 zzLegion-R7000P% git log …

LabVIEWCompactRIO 开发指南23 Web服务

LabVIEWCompactRIO 开发指南23 Web服务 LabVIEW8.6中引入的LabVIEWWeb服务提供了一种开放的标准方式&#xff0c;可通过Web与VI进行通信。考虑一个部署在分布式系统中的LabVIEW应用程序。LabVIEW提供了网络流等功能来建立通信&#xff0c;但许多开发人员需要一种方式&#xf…

Cy7 NHS ester水溶性七甲川花菁染料标记活性脂477908-53-5

Sulfo-CY7 NHS ester是一种荧光标记试剂&#xff0c;可用于生物分子的荧光标记。它是一种水溶性的N-羟基琥珀酰亚胺酯化合物&#xff0c;具有强烈的荧光信号和高度稳定性。Sulfo-CY7 NHS ester的化学结构为C43H48N3NaO16S2&#xff0c;分子量约为968.98 g/mol。Sulfo-CY7 NHS e…

HTML5 新增的input 类型、新增的表单属性

新增的input 类型 属性值 说明 type"emall" 限制用户输入必须为Emall类型(邮箱) type"url"限制用户输入必须为URL类型(网址)type"dade"限制用户输入必须为日期类型type"time"限制用户输入必须为时间类型type"month"限…

2023年,企业数字化转型的大趋势

数字化转型&#xff08;DX&#xff09;一直是IT界的热门词汇&#xff0c;它会在组织规划中发挥更大的作用。因为完成数字化转型的组织&#xff0c;通常工作效率、生产力都会更高&#xff0c;运营成本也会降低。 一、自动化将为规范性指导提供动力 在过去十年里&#xff0c;数…

Redis数据类型-ZSet

一. 概述 SortedSet又叫zset&#xff0c;它是Redis提供的特殊数据类型&#xff0c;是一种特殊的set类型&#xff0c;继承了set不可重复的特点&#xff0c;并在set基础上为每个值添加一个分数&#xff0c;用来实现值的有序排列。 二. 常用指令 明白它的特点后&#xff0c;接下来…

OpenAI-whisper语音识别模型

1、whisper简介 Whisper是一个通用的语音识别模型。它是在不同音频的大型数据集上训练的&#xff0c;也是一个多任务模型&#xff0c;可以执行多语言语音识别、语音翻译和语言识别。 whisper有五种模型尺寸&#xff0c;提供速度和准确性的平衡&#xff0c;其中English-only模型…

使用 VS Code 快速搭建 ESP-IDF 开发环境 (Windows、Linux、MacOS)

ESP-IDF 是乐鑫官方的物联网开发框架&#xff0c;适用于 ESP32、ESP32-S、ESP32-C 和 ESP32-H 系列 SoC。它基于 C/C 语言提供了一个自给自足的 SDK&#xff0c;方便用户在这些平台上开发通用应用程序&#xff0c;并集成了大量的软件组件&#xff0c;包括 RTOS、外设驱动程序、…

Flutter 桌面开发 | 键盘快捷键功能 - Shortcuts 组件

theme: cyanosis 在桌面端的开发中&#xff0c;键盘快捷键是非常常见而必要的&#xff0c;比如 Ctrl F 搜索&#xff0c; Ctrl C 复制等。Flutter 既然可以开发桌面端应用&#xff0c;那必然要提供自定义快捷键&#xff0c;触发事件的功能支持。这就是本节要介绍的 Shortcuts…

【5.19】三、白盒测试方法—程序插桩法

目录 3.2 程序插桩法 3.2.1 目标代码插桩 3.2.2 源代码插桩 小提示&#xff1a;HeisenBugs 黑盒测试和白盒测试的异同 3.2 程序插桩法 程序插桩法是一种被广泛使用的软件测试技术&#xff0c;由J.C.Huang教授提出。简单来说&#xff0c;程序插桩就是往被测试程序中插入测…

合肥工业大学计算机组成原理课设-系统硬件综合设计

✅作者简介&#xff1a;CSDN内容合伙人、信息安全专业在校大学生&#x1f3c6; &#x1f525;系列专栏 &#xff1a;信息安全本科生课设-系统硬件综合设计报告 &#x1f4c3;新人博主 &#xff1a;欢迎点赞收藏关注&#xff0c;会回访&#xff01; &#x1f4ac;舞台再大&#…

Varnish代理服务器

一.Varnish概述 1.Varnish 简介 Varnish是一款高性能且开源的反向代理服务器和HTTP加速器&#xff0c;其采用全新的软件体系机构&#xff0c;和现在的硬件体系紧密配合。与传统的squid相比&#xff0c;Varnish具有高性能、速度快、管理更加方便等优点&#xff0c;目前很多大型…

Python:如何基于滑动窗口进行气候因子间的相关系数分析?(逐像元)

目录 01 常规的相关系数简单说明 02 滑动窗口下的相关系数分析 最近处理一些气候因子的统计分析&#xff0c;遇到一些问题&#xff0c;记录一下。 01 常规的相关系数简单说明 在研究滑动窗口前&#xff0c;我们先来研究一下常规的相关系数分析&#xff0c;为了简化问题&…

《The Element of Style》阅读笔记 —— 章节 I Elementary Rules of Usage

前言&#xff1a;本科期间担任科研助理时&#xff0c;有幸从导师那里借来这本书通读&#xff0c;只记得自己当时在本子上做了一些笔记&#xff0c;但是想不起来具体记了什么&#x1f602;前段时间再次从学院的讲座活动中听闻这本书&#xff0c;决定重温一遍&#xff0c;本篇为此…

实验一 结构化分析与设计——数据流图DFD与模块结构图SC

一、实验目的&#xff1a; 掌握传统结构化分析方法中功能建模的基本思想&#xff0c;即数据流分析技术。数据流图DFD是软件系统的逻辑模型&#xff0c;描绘数据在系统中从输入到输出所经历的变换&#xff08;即加工处理&#xff09;。 同时&#xff0c;了解变换型和事务型数据…

Copernicus DEM 30 metre dataset now freely available01 December 2020

欧空局宣布,除2019年发布的哥白尼DEM 90米分辨率外,30米分辨率数据的访问权限现已延长,数据集对任何注册用户开放和免费。 自2019年以来,哥白尼方案配备了全球一致的高分辨率数字高程模型,供所有用户使用,以处理各种应用。 哥白尼DEM结合了平坦的水体、连贯的河流流、编…

外汇客户收支风险管理系统助力外汇业务便利化

外管局2019年开始发文推行跨境投资便利化政策&#xff0c;2023年商务部等17部门又发文支持贸易外汇收支便利化政策&#xff0c;从一个小范围试点政策&#xff0c;到各部委大力推广支持&#xff0c;银行业内重点推广&#xff0c;这3年间外汇业务便利化经历了什么&#xff1f; …

狂飙,ChatGPT 官方 iOS 版本应用上线

ChatGPT正式发布App&#xff0c;可在苹果应用商店下载&#xff0c;安卓版也不远了 在手机上也能玩ChatGPT了&#xff01;当地时间周四&#xff08;5月18日&#xff09;&#xff0c;人工智能研究公司OpenAI在官网宣布&#xff0c;其在美国推出了聊天机器人ChatGPT的iPhone应用&a…

写公开信可别等被喷,才发现其实可以这样

正文共 1022 字&#xff0c;阅读大约需要 4 分钟 公务员必备技巧&#xff0c;您将在4分钟后获得以下超能力&#xff1a; 快速生成公开信 Beezy评级 &#xff1a;B级 *经过简单的寻找&#xff0c; 大部分人能立刻掌握。主要节省时间。 推荐人 | Kim 编辑者 | Linda ●图片由Le…

Unity A* Pathfinding Project

先下载免费版 https://arongranberg.com/astar/download# 教程首页 https://arongranberg.com/astar/docs/getstarted.html 创建一个plane 当地面 创建一个gameobject 添加组件 PathFinder 长这样 调整每个格子大小的 创建两个layer 一个是阻挡物的 一个是地面的 这里填入阻…