(动画详解)LeetCode225.用队列实现栈

. - 力扣(LeetCode)

题目描述

解题思路

这道题的思路就是使用两个队列来实现

入栈就是入队列

出栈就是将非空队列的前n-1个元素移动到新的队列中去

再将最后一个元素弹出

动画详解

代码实现

 

#define _CRT_SECURE_NO_WARNINGS 1

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

typedef int QDataType;

typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType x;
}QNode;

// 使用另一个结构体来存储头尾指针,指向队列的头尾
typedef struct Queue
{
	QNode* phead;
	QNode* ptail;
	int size;
}Queue;

void QueueInit(Queue* pq)
{
	assert(pq);
	pq->phead = NULL;
	pq->ptail = NULL;
	pq->size = 0;
}

void QueueDestroy(Queue* pq)
{
	assert(pq);

	QNode* cur = pq->phead;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);

		cur = next;
	}

	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

// 队尾插入
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);

	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		return;
	}

	newnode->next = NULL;
	newnode->x = x;

	if (pq->ptail == NULL)
	{
		pq->phead = pq->ptail = newnode;
	}
	else
	{
		pq->ptail->next = newnode;
		pq->ptail = newnode;
	}

	pq->size++;
}

// 队头删除
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->size != 0);

	/*QNode* next = pq->phead->next;
	free(pq->phead);
	pq->phead = next;

	if (pq->phead == NULL)
		pq->ptail = NULL;*/

		// 一个节点
	if (pq->phead->next == NULL)
	{
		free(pq->phead);
		pq->phead = pq->ptail = NULL;
	}
	else // 多个节点
	{
		QNode* next = pq->phead->next;
		free(pq->phead);
		pq->phead = next;
	}

	pq->size--;
}

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->phead);

	return pq->phead->x;
}

QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->ptail);

	return pq->ptail->x;
}


int QueueSize(Queue* pq)
{
	assert(pq);

	return pq->size;
}

bool QueueIsEmpty(Queue* pq)
{
	assert(pq);

	return pq->size == 0;
}

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


MyStack* myStackCreate()
{
	// 使用malloc开辟新的栈,防止局部变量出作用域之后被销毁
	// 不能使用全局变量,因为下一次调用的时候全局变量不会初始化
	MyStack* obj = (MyStack*)malloc(sizeof(MyStack));
	// 调用队列初始化函数对两个队列进行初始化
	QueueInit(&(obj->q1));
	QueueInit(&(obj->q2));
	return obj;
}

void myStackPush(MyStack* obj, int x)
{
	// 向不为空的队列插入数据
	if (QueueIsEmpty(&obj->q1))
	{
		QueuePush(&(obj->q1), x);
	}
	else
	{
		QueuePush(&(obj->q2), x);
	}
}

int myStackPop(MyStack* obj)
{
	// 将前size-1个数据弹出,导入到不为空的队列中去,再删除非空队列中的最后一个数据
	// 使用假设法来判断空队列
	Queue* empty = &(obj->q1);
	Queue* notempty = &(obj->q2);
	if (!QueueIsEmpty(&(obj->q1)))
	{
		notempty = &(obj->q1);
		empty = &(obj->q2);
	}
	// 开始遍历
	while (QueueSize(notempty) > 1)
	{
		// 向空队列中插入非空队列中的数据
		QueuePush(empty, QueueFront(notempty));
		// 弹出非空队列的数据
		QueuePop(notempty);
	}
	int top = QueueFront(notempty);
	// 弹出非空队列中的最后一个数据,实现出栈操作
	QueuePop(notempty);
	return top;
}

int myStackTop(MyStack* obj)
{
	if (!QueueIsEmpty(&obj->q1))
	{
		return QueueBack(&obj->q1);
	}
	else
	{
		return QueueBack(&obj->q2);
	}
}

bool myStackEmpty(MyStack* obj)
{
	return QueueIsEmpty(&(obj->q1)) && QueueIsEmpty(&(obj->q2));

}

void myStackFree(MyStack* obj)
{
	// 不能直接释放obj,因为还有剩下的链表没有释放,将成为野指针
	QueueDestroy(&obj->q1);
	QueueDestroy(&obj->q2);
	free(obj);
}

/**
 * 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);
*/

复杂度分析

我们可以发现,这个代码仅有在将非空队列的元素导入空队列时有循环,因此时间复杂度为O(n)

总结

Bye!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

打车遇到臭车的底层逻辑!修炼的法门居然又捡起来了!——早读(逆天打工人爬取热门微信文章解读)

冥冥之中自有天意 引言Python 代码第一篇 洞见 热搜上“打车遇到臭车”话题&#xff0c;戳到了650万成年人的尴尬第二篇 冯站长之家 三分钟新闻早餐结尾 生命不息 探索不止 在生命的旅程中 我不断探索不断发现 永不停歇 引言 记 ​一大突破 炁​机启动 ​没想到 ​去年9月份…

【NodeMCU实时天气时钟温湿度项目 3】连接SHT30传感器,获取并显示当前环境温湿度数据(I2C)

今天&#xff0c;我们开始第三个专题&#xff1a;连接SHT30温湿度传感器模块&#xff0c;获取当前环境实时温湿度数据&#xff0c;并显示在1.3寸TFT液晶显示屏上。 第一专题内容&#xff0c;请参考 【NodeMCU实时天气时钟温湿度项目 1】连接点亮SPI-TFT屏幕和UI布局设计…

【0day漏洞复现】中移铁通禹路由器信息泄露漏洞

0x01 阅读须知 “如棠安全的技术文章仅供参考&#xff0c;此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等&#xff08;包括但不限于&#xff09;进行检测或维护参考&#xff0c;未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供…

AJAX家政系统源码部署/售后更新/搭建/上线维护

基于FastAdmin和原生微信小程序开发的一款同城预约、上门服务、到店核销家政系统&#xff0c;用户端、服务端(高级授权)、门店端(高级授权)各端相互依赖又相互独立&#xff0c;支持选择项目、选择服务人员、选择门店多种下单方式&#xff0c;支持上门服务和到店核销两种服务方式…

收放卷控制系统详细算法介绍(全伺服系统)

收放卷控制系统涉及的内容非常多,这里我们介绍全伺服系统利用电子齿轮指令实现主从轴的比例随动速度控制,收放卷控制算法介绍常用链接如下 1、收放卷+排线控制 收放卷+排线控制系统框图-CSDN博客文章浏览阅读24次。1、收放卷前馈量计算FC收放卷前馈量计算FC(CODESYS ST源代…

基于51单片机的智能导盲手杖—超声波测距

基于51单片机的智能导盲手杖 &#xff08;仿真&#xff0b;程序原理图&#xff0b;PCB设计报告&#xff09; 功能介绍 具体功能&#xff1a; 1.显示前方障碍物距离。 2.实时测量距离&#xff0c;并通过蜂鸣器提醒距离过短&#xff0c;蜂鸣器蜂鸣发出预警。 3.可以通过按键调…

IP代理对矩阵养号带来哪些帮助?

IP代理技术在矩阵养号策略中发挥着不可忽视的作用&#xff0c;特别是在当今这个信息爆炸、网络高度发达的时代。矩阵养号&#xff0c;尤其是抖音等社交媒体平台的矩阵养号&#xff0c;旨在通过精心策划和管理多个账号&#xff0c;实现内容的多元化展示、提升曝光率和互动率&…

.NET WebService \ WCF \ WebAPI 部署总结 以及 window 服务 调试

一、webservice 部署只能部署IIS上&#xff0c; 比较简单&#xff0c;就不做说明了 二、 WCF 部署 1 部署到IIS 跟部署 webservice 部署方法一样的 wcf 部署2 部署到控制台 要以管理员运行vs&#xff0c;或者 管理员运行 控制台的exe 在控制器项目中 创建IUserInfoService 接口…

AC/DC电源模块的市场发展与前景分析

BOSHIDA AC/DC电源模块的市场发展与前景分析 AC/DC电源模块是一种将交流电转化为直流电的电子设备&#xff0c;广泛应用于各种电子设备和系统中。随着电子技术的快速发展&#xff0c;AC/DC电源模块的市场也在不断扩大&#xff0c;并且具有良好的发展前景。 一&#xff0c;AC/…

【管理咨询宝藏99】离散制造智能工厂战略规划方案

本报告首发于公号“管理咨询宝藏”&#xff0c;如需阅读完整版报告内容&#xff0c;请查阅公号“管理咨询宝藏”。 【管理咨询宝藏99】离散制造智能工厂战略规划方案 【格式】PDF版本 【关键词】智能制造、先进制造业转型、数字化转型 【核心观点】 - 推进EHS、品质一致性、生…

模电·基本共集放大电路

基本共集放大电路 一、电路的组成二、静态分析三、动态分析 一、电路的组成 根据放大电路的组成原则&#xff0c;晶体管应工作在放大区&#xff0c;即 u B E > U o n {\large u\tiny BE}>{U\tiny on} uBE>Uon&#xff0c; u C E ≥ u B E {\large u\tiny CE}≥{\large…

吴恩达机器学习笔记:第 9 周-17大规模机器学习(Large Scale Machine Learning)17.3-17.4

目录 第 9 周 17、 大规模机器学习(Large Scale Machine Learning)17.3 小批量梯度下降17.4 随机梯度下降收敛 第 9 周 17、 大规模机器学习(Large Scale Machine Learning) 17.3 小批量梯度下降 小批量梯度下降算法是介于批量梯度下降算法和随机梯度下降算法之间的算法&…

全新策略打造智慧公厕,引领智慧城市公共卫生的信息化发展

智慧公厕的建设至关重要&#xff0c;要确保高质量、高效率&#xff0c;并以人民为中心。在规划方面&#xff0c;融合各种高精尖的技术是必不可少的。而在使用方面&#xff0c;提供更多贴心智能设备是体现温度的关键。让人民群众能够享受到更多的获得感、幸福感和安全感&#xf…

彩虹易支付用户中心美化主题

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 使用本主题前请备份官方版本文件再进行解压到user目录替换&#xff01;&#xff01;&#xff01; 二、效果展示 1.部分代码 代码如下&#xff08;示例&#xff09;&#xff1a; &…

Java设计模式 _行为型模式_命令模式

一、命令模式 1、命令模式 命令模式&#xff08;Command Pattern&#xff09;是一种行为型模式&#xff0c;一种数据驱动的设计模式。命令模式中请求以命令的形式包裹在对象中&#xff0c;即将命令封装为类&#xff0c;从而可以使用不同的请求&#xff0c;队列等操作具体的对象…

VUE 或 Js封装通用闭包循环滚动函数

1、vue3 闭包滚动函数的使用 js 调用也基本雷同 // 滚动Tab组件const scoreTabRef ref()// 滚动的选项const scrollOption ref({// 滚动的Dom元素scrollDom: null,// 滚动的时间间隔scrollInterval: 1500,// 滚动的距离scrollSep: 100,// 滚动历时时间scrollDuration: 10…

BMJ英国医学杂志文献去哪里下载

《柳叶刀》The Lancet、《新英格兰医学期刊》NEJM、《美国医学会杂志》JAMA、《英国医学期刊》BMJ是世界四大医学顶尖期刊&#xff0c;今天有位医学同学求助一篇BMJ英国医学杂志文献&#xff0c;下面就用这篇文献演示一下在家获取BMJ文献的方法及过程。 文献名&#xff1a;Sur…

Flutter 首次亮相 Google Cloud Next 大会

作者 / Kelvin Boateng Flutter 团队在近期首次参加了 Google Cloud Next 大会&#xff0c;这意味着 Flutter 在开发社区中的影响力正在日益增长。 Google Cloud Next https://cloud.withgoogle.com/next 我们与 Google Cloud、Firebase、Very Good Ventures 和 Serverpod 的团…

【C++】类与对象(类章节)

面向过程和面向对象 C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解决问题。 C是基于面向对象的&#xff0c;关注的是对象&#xff0c;将一件事情拆分成不同的对象&#xff0c;靠对象之间的交互完 成。 一、类 1.类…

【算法】高精度乘法

前言 最近在参加某个比赛的时候遇到了这个问题&#xff0c;用字符串表示时&#xff0c;长度能达到15&#xff0c;所以针对大数乘法写一篇文章。 高精度 * 低精度 在这种场景下&#xff0c;一般都是给定一个无法用int或long long 存储的数&#xff0c;再给定一个能用int或lon…