[C/C++] 数据结构 LeetCode:用队列实现栈

题目描述:

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(pushtoppop 和 empty)。

实现 MyStack 类:

  • void push(int x) 将元素 x 压入栈顶。
  • int pop() 移除并返回栈顶元素。
  • int top() 返回栈顶元素。
  • boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

注意:

  • 你只能使用队列的基本操作 —— 也就是 push to backpeek/pop from frontsize 和 is empty 这些操作。
  • 你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。

题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

功能实现思路:

在实现这个题目之前得先完成队列的基本操作,可以参考文章:http://t.csdnimg.cn/3v2IZ

1. 出栈 

现在我们有两个队列,假设在第一个队列里依次入了1 2 3 4 5,另一个队列为空队列

现在要出栈的话,应该把5出去,但是数据目前在队列里,出数据只能从队头出,所以可以把1 2 3 4依次出队列,并入到第二个队列中,此时就可以把5出去了,此时又是一个队列为空,另一个存着剩余的数据,再出栈的话,还按照这个方法即可

int myStackPop(MyStack* obj) {
    //由于不知道哪个队列为空队列,可以采用假设法
    Queue* empty = &obj->queue1;
    Queue* nonempty=&obj->queue2;
    if(!QueueEmpty(&obj->queue1))
    {
        empty=&obj->queue2;
        nonempty=&obj->queue1;
    }
    
    while(QueueSize(nonempty)>1)
    {
        QueuePush(empty,QueueFront(nonempty));
        QueuePop(nonempty);
    }
    int top=QueueFront(nonempty);
    QueuePop(nonempty);
    return top;
}

总结:

出栈操作相当于非空队列的队尾元素出队,此时需要把非空队列除最后一个元素之外的其他元素入队到空队列,然后出队最后一个队尾元素

2.入栈

入栈操作相当于在非空队列进行入队操作


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

3.判空

只要两个队列都没有元素就表示栈空

bool myStackEmpty(MyStack* obj) {
    return QueueEmpty(&obj->queue1)&&QueueEmpty(&obj->queue2);
}

4.返回栈顶元素

即返回非空队列队尾元素

int myStackTop(MyStack* obj) {
    if(!QueueEmpty(&obj->queue1))
    {
        return QueueTail(&obj->queue1);
    }
    else
    {
        return QueueTail(&obj->queue2);
    }
}
typedef int QDataType;
typedef struct QueueNode {
	QDataType x;
	struct QueueNode* next;
}Node;

typedef struct Queue
{
	Node* head;
	Node* tail;
	int size;
}Queue;

void QueueInit(Queue* ps);
void QueuePush(Queue* ps,QDataType x);
void QueuePop(Queue* ps);
bool QueueEmpty(Queue* ps);
QDataType QueueFront(Queue* ps);
QDataType QueueTail(Queue* ps);
int QueueSize(Queue* ps);
void QueueDestory(Queue* ps);

void QueueInit(Queue* ps)
{
	assert(ps);

	ps->head = ps->tail = NULL;
	ps->size = 0;
}

void QueuePush(Queue* ps, QDataType x)
{
	assert(ps);
	//创建新节点
	Node* newnode = (Node*)malloc(sizeof(Node));
	if (newnode == NULL)
	{
		perror("malloc");
		return;
	}
	newnode->next = NULL;
	newnode->x = x;

	//尾插
	if (ps->tail == NULL)
	{
		ps->head = ps->tail = newnode;
	}
	else
	{
		ps->tail->next = newnode;
		ps->tail = ps->tail->next;
	}
	ps->size++;
}

void QueuePop(Queue* ps)
{
	assert(ps);
	assert(ps->head);

	if (ps->head->next == NULL)
	{
		ps->head = ps->tail = NULL;
	}
	else
	{
		Node* next = ps->head->next;
		free(ps->head);
		ps->head = next;
	}
	
	ps->size--;
}

bool QueueEmpty(Queue* ps)
{
	assert(ps);

	return ps->tail == NULL;
}

QDataType QueueFront(Queue* ps)
{
	assert(ps);
	assert(ps->head);

	return ps->head->x;
}

QDataType QueueTail(Queue* ps)
{
	assert(ps);
	assert(ps->tail);

	return ps->tail->x;
}

int QueueSize(Queue* ps)
{
	assert(ps);
	return ps->size;
}

void QueueDestory(Queue* ps)
{
	assert(ps);

	Node* cur = ps->head;
	while (cur)
	{
		Node* next = cur->next;
		free(cur);
		cur = next;
	}

	ps->head=ps->tail = NULL;
    ps->size=0;
}

typedef struct {
    Queue queue1;
    Queue queue2;
} MyStack;


MyStack* myStackCreate() {
    MyStack* mystack=(MyStack*)malloc(sizeof(MyStack));
    QueueInit(&mystack->queue1);
    QueueInit(&mystack->queue2);
    return mystack;
}

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

int myStackPop(MyStack* obj) {
    Queue* empty = &obj->queue1;
    Queue* nonempty=&obj->queue2;

    if(!QueueEmpty(&obj->queue1))
    {
        empty=&obj->queue2;
        nonempty=&obj->queue1;
    }
    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->queue1))
    {
        return QueueTail(&obj->queue1);
    }
    else
    {
        return QueueTail(&obj->queue2);
    }
}

bool myStackEmpty(MyStack* obj) {
    return QueueEmpty(&obj->queue1)&&QueueEmpty(&obj->queue2);
}

void myStackFree(MyStack* obj) {

    QueueDestory(&obj->queue1);
    QueueDestory(&obj->queue2);

    free(obj);
}

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

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

相关文章

Vulhub靶场-KIOPTRIX: LEVEL 1.1

目录 环境配置 端口扫描 漏送发现 漏送利用 提权(内核漏洞提权) 环境配置 环境配置的过程同主页该专栏第一个靶场,不在赘述。 端口扫描 首先通过arp-scan并根据靶机的mac地址确定靶机的IP地址 然后对靶机进行一个扫描 首先扫描到OpenS…

Python大数据之linux学习总结——day10_hive调优

hive调优 hive调优hive命令和参数配置1.hive数据压缩压缩对比开启压缩 2.hive数据存储[练习]行列存储原理存储压缩比拓展dfs -du -h 3. fetch抓取4. 本地模式5. join的优化操作6. 列裁剪7. 分区裁剪8. group by 操作9. count(distinct)10. 笛卡尔积11. 动态分区[练习]12. 如何调…

【C++】入门三

接下来我们说一下引用这个概念,那么什么是引用呢?简单来说引用就是取别名,比如有一个变量叫a,现在我给它取了一个别名叫b,那么此时a和b管理的都是一块空间 这个例子就可以很好的体现a和b管理的是同一块空间&#xff0…

2023.11.18 每日一题(AI自生成应用)【C++】【Python】【Java】【Go】 动态时间序列分析

目录 一、编程挑战:动态时间序列分析 实际应用: 实现提示: 二、实现 1. C 2. Python 3. JAVA 4. Go 一、编程挑战:动态时间序列分析 问题描述: 假设你是一名软件工程师,需要开发一个应用来分析和预…

Spark 平障录

Profile Profile 是最重要的第一环。 利用好 spark UI 和 yarn container log分析业务代码,对其计算代价进行预判建设基准,进行对比,比如application id 进行对比,精确到 job DAG 环节 充分利用 UI Stage 页面 页头 summary&…

java拼图游戏(待优化)

启动类 package com.yx.ui;public class App { //启动入口public static void main(String[] args) {//如果想要开启一个界面,就创建谁的对象 // new DengJFrame(); // new ZCJFrame();new GameJFrame();}}游戏类 package com.yx.ui;import java.awt.event.KeyEv…

【数据结构】前言

数据结构是在计算机中维护数据的方式。 数据结构是OI重要的一部分。 同的数据结构各有优劣,能够处理的问题各不相同,而根据具体问题选取合适的数据结构,可以大大提升程序的效率。 所以,学习各种各样的数据结构是很有必要的。 数据…

Infineon+EB构建MCAL驱动包Demo实现片内外设使用

本篇文章以实际MCAL示例程序的实现与使用,帮助读者理解MCAL层在BSW中具体担任的功能与角色。文章首先介绍了为了构建MCAL示例程序所需要的相关应用程序的安装;然后介绍了个软件相互集成配置的过程,达到可以编译生成可执行文件;最后…

055-第三代软件开发-控制台输出彩虹日志

第三代软件开发-控制台输出彩虹日志 文章目录 第三代软件开发-控制台输出彩虹日志项目介绍控制台输出彩虹日志实现原理真实代码 总结 关键字: Qt、 Qml、 关键字3、 关键字4、 关键字5 项目介绍 欢迎来到我们的 QML & C 项目!这个项目结合了 QM…

054-第三代软件开发-信号槽

第三代软件开发-信号槽 文章目录 第三代软件开发-信号槽项目介绍信号槽实现原理与MFC消息映射机制区别Qt信号槽机制的优缺点 关键字: Qt、 Qml、 关键字3、 关键字4、 关键字5 项目介绍 欢迎来到我们的 QML & C 项目!这个项目结合了 QML&#x…

网络层——IP协议

文章目录 一.IP协议二.基本概念三.IP协议格式四.分片与组装五.网段划分六.特殊的IP地址七.IP地址的数量限制八.私网IP地址和公网IP地址九.路由十.路由表生成算法 一.IP协议 IP协议全称为“网际互连协议(Internet Protocol)”,IP协议是TCP/IP…

视频合并:掌握视频嵌套合并技巧,剪辑高手的必备秘籍

在视频剪辑的过程中,掌握视频合并的技巧是每个剪辑高手必备的技能之一。通过合理的合并视频,可以增强视频的视觉效果,提高观看体验。 一、视频合并的准备工作 收集素材:在进行视频合并之前,首先需要收集足够的素材&a…

C语言 深入理解指针

目录 前言 指针的重要概念 剖析 题目一 题目二 题目三 题目四 题目五 题目六 题目七 题目八 **cpp *--*cpp 3 *cpp[-2] 3 cpp[-1][-1] 1 前言 简单来说,指针是一个变量,其值为另一个变量的地址。通过指针,我们可以直…

交易机器人-规则部分

微信公众号:大数据高性能计算 背景 背景是基于人工去做交易本身无法做到24小时无时无刻的交易,主要是虚拟币本身它是24小时交易,人无法做到24小时盯盘,其次就是如果你希望通过配置更加复杂的规则甚至需要爬取最新的信息走模型进行…

二阶低通滤波器(二阶巴特沃斯滤波器)

连续传递函数G(s) 离散传递函数G(z) 差分方程形式 二阶巴特沃斯滤波器参数设计 设计采样频率100Hz,截止频率33Hz。 注意:设计参数使用在离散系统中! 同理,其他不同阶数不同类型的滤波器设计,如二阶高通滤波器、二阶…

OFDM通信系统仿真之交织技术

文章目录 前言一、交织1、概念2、图形举例3、交织的位置 二、MATLAB仿真1、MATLAB 程序2、仿真结果 前言 之前的博客:OFDM深入学习及MATLAB仿真 中有对交织的概念进行讲解,但讲解还是比较浅显,且仿真实现时并没有加入交织及解交织流程&#…

系列十二、强引用、软引用、弱引用、虚引用分别是什么?

一、整体架构 二、强引用(默认支持模式) 2.1、概述 当内存不足时,JVM开始垃圾回收,对于强引用的对象,就算是出现了OOM也不会对该对象进行回收,死都不收。 强引用是我们最常见的普通对象引用,只…

特效!视频里的特效在哪制作——Adobe After Effects

今天,我们来谈谈一款在Adobe系列中推出的一款图形视频处理软件,适用于从事设计和视频特技的机构,包括电视台、动画制作公司、个人后期制作工作室以及多媒体工作室的属于层类型后期软件——Adobe After Effects。 Adobe After Effects&#xf…

苍穹外卖项目笔记(3)——员工管理

前言 这些功能都没有展示对应的测试结果,可自行通过接口文档进行测试,也可以进行前后端联调测试,附代码链接:take-out 1新增员工 1.1 需求分析和设计 产品原型 接口设计 【注】code:操作成功返回1,否则…

Azure Machine Learning - Azure AI 搜索中的集成数据分块和嵌入

在基于索引器的索引编制中,Azure AI _集成矢量化_将数据分块和文本到矢量嵌入添加到技能中,它还为查询添加文本到矢量的转换。 关注TechLead,分享AI全维度知识。作者拥有10年互联网服务架构、AI产品研发经验、团队管理经验,同济本…