LeetCode—用队列实现栈

一.题目

二.思路

1.后入先出的实现:

创建两个队列来实现栈(后入先出):

两个队列,保持一个存数据,另一个为空,入数据(push)要入不为空的队列,(pop)时要把非空队列的前size-1个数据转移到空队列中,所剩下的数据就是我们要出的数据(pop)。

2.图示: 

3.整体实现

 这里我们将队列q1,q2封装在结构体MyStack中,所以我们的关系构架为:

(1)初始化

为了防止局部变量出作用域后销毁,这里要malloc新的结构体。

MyStack* myStackCreate() 
{
    MyStack* st=(MyStack*)malloc(sizeof(MyStack));
    if(st==NULL)
        return false;
    
    QueueInit(&st->q1);
    QueueInit(&st->q2);
 
    return st;
}

 (2)入数据

入数据时要入非空队列中去

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

(3)出数据

为保证后入先出,我们将非空队列的前size-1个数据转移到空队列中去,剩下来的那一个数据就是栈顶元素。

int myStackPop(MyStack* obj) 
{
    Queue* tmp=&obj->q1;
    Queue* notmp=&obj->q2;
 
    if(QueueSize(notmp)==0)
    {
        tmp=&obj->q2;
        notmp=&obj->q1;
    }
 
    while(QueueSize(notmp)>1)
    {
        QueuePush(tmp,QueueFront(notmp));
        QueuePop(notmp);
 
    }
 
    QDataType res=QueueFront(notmp);
    QueuePop(notmp);
    return res;
}

 (4)返回栈顶元素

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

 (5)判空

两个队列都为空才能说明栈是空的

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

(6)销毁

要先将两个队列销毁,再销毁结构体obj。

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

三.参考代码

typedef int QDataType;
 
typedef struct QNode
{
	struct QNode* next;
	QDataType data;
}QNode;
 
typedef struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
}Queue;
 
void QueueInit(Queue* pq);
void QueueDestory(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;
	pq->size = 0;
}
void QueueDestory(Queue* pq)
{
	assert(pq);
 
	QNode* cur =pq->head;
 
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
 
	pq->head = pq->tail = NULL;
	pq->size = 0;
}
 
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* tmp = (QNode*)malloc(sizeof(QNode));
	if (tmp == NULL)
	{
		perror("malloc failed");
		exit(-1);
	}
	tmp->next = NULL;
	tmp->data = x;
 
	if (pq->head == pq->tail && pq->head == NULL)
	{
		pq->head = pq->tail = tmp;
	}
	else
	{
		pq->tail->next = tmp;
		pq->tail = tmp;
	}
	pq->size++;
}
void QueuePop(Queue* pq)
{
	assert(pq);
 
	assert(pq->head != NULL);
 
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
    
	pq->size--;
}
 
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);
	return pq->size == 0;
}
int QueueSize(Queue* pq)
{
	assert(pq);
 
	return pq->size;
}
 
typedef struct 
{
    Queue q1;
    Queue q2;
} MyStack;
 
 
MyStack* myStackCreate() 
{
    MyStack* st=(MyStack*)malloc(sizeof(MyStack));
    if(st==NULL)
        return false;
    
    QueueInit(&st->q1);
    QueueInit(&st->q2);
 
    return st;
}
 
void myStackPush(MyStack* obj, int x) 
{
    if(QueueSize(&obj->q1)!=0)
    {
        QueuePush(&obj->q1,x);
    }
    else
    {
        QueuePush(&obj->q2,x);
    }
}
 
int myStackPop(MyStack* obj) 
{
    Queue* tmp=&obj->q1;
    Queue* notmp=&obj->q2;
 
    if(QueueSize(notmp)==0)
    {
        tmp=&obj->q2;
        notmp=&obj->q1;
    }
 
    while(QueueSize(notmp)>1)
    {
        QueuePush(tmp,QueueFront(notmp));
        QueuePop(notmp);
 
    }
 
    QDataType res=QueueFront(notmp);
    QueuePop(notmp);
    return res;
}
 
int myStackTop(MyStack* obj) 
{
    if(QueueSize(&obj->q1)!=0)
        return QueueBack(&obj->q1);
    else
        return QueueBack(&obj->q2);
}
 
bool myStackEmpty(MyStack* obj) 
{
    return QueueEmpty(&obj->q1)  &&  QueueEmpty(&obj->q2);
}
 
void myStackFree(MyStack* obj) 
{
    QueueDestory(&obj->q1);
    QueueDestory(&obj->q2);
 
    free(obj);
}

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

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

相关文章

Linux基础之进程的基本概念

目录 一、进程的基本概念 1.1 什么是进程 1.2 PCB的概念 1.3 进程的查看 1.3.1 查看进程方式一 1.3.2 查看进程的方式二 1.4 父进程与子进程 一、进程的基本概念 1.1 什么是进程 进程是什么? 课本概念:程序的一个执行实例,正在执行的…

Linux学习笔记8---官方 SDK 移植实验

在上一章中,我们参考 ST 官方给 STM32 编写的 stm32f10x.h 来自行编写 I.MX6U 的寄存器定义文件。自己编写这些寄存器定义不仅费时费力,没有任何意义,而且很容易写错,幸好NXP 官方为 I.MX6ULL 编写了 SDK 包,在 SDK 包…

基于springboot+vue+Mysql的校园闲置物品租售系统

开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…

C++小程序:同一路由器下两台计算机间简单通信(2/2)——客户端

客户端的程序结构前半部分与服务器端基本相同,后半部分也相对简单。相关函数的解释可以参考前文服务器端的内容。有关客户端的内容除个别地方外,就不再做长篇大论的解释。强调一点,如果将此程序移到其它电脑上运行,编译需要releas…

Linux网络编程】传输层中的TCP和UDP(UDP篇)

【Linux网络编程】传输层中的TCP和UDP(UDP篇) 目录 【Linux网络编程】传输层中的TCP和UDP(UDP篇)传输层再谈端口端口号范围划分认识知名端口号netstatiostatpidofxargs UDP协议UDP协议端格式UDP的特点面向数据报UDP的缓冲数据UDP使…

20-LINUX--网络编程

一. 主机字节序列和网络字节序列 主机字节序列分为大端字节序和小端字节序,不同的主机采用的字节序列可能不同。大 端字节序是指一个整数的高位字节存储在内存的低地址处,低位字节存储在内存的高地址 处。小端字节序则是指整数的高位字节存储在内存的高…

CentOS 8.5 安装配置 Tinyproxy 轻量代理服务器 Windows10 系统设置http代理 详细教程

1 下载 下载地址 2 上传服务器并解压 tar zxvf tinyproxy-1.11.2.tar.gz 3 安装配置 #安装依赖软件 yum install automake cd tinyproxy-1.11.2/ #生成configure ./autogen.sh # ./configure --prefix/usr/local/tinyproxy make make install 4 配置环境 vim /etc/prof…

四川汇昌联信:拼多多运营属于什么行业?

拼多多运营属于什么行业?这个问题看似简单,实则涉及到了电商行业的深层次理解。拼多多运营,顾名思义,就是在拼多多这个电商平台上进行商品销售、推广、客户服务等一系列活动。那么,这个行业具体包含哪些内容呢?下面就从四个不同…

【计算机毕业设计】用于日语词汇学习的微信小程SSM

日语词汇学习小程序是高校人才培养计划的重要 组成部分,是实现人才培养目标、培养学生科研能力与创新思维、检验学生综合素质与实践能力的重要手段与综合性实践教学环节。本学生所在学院多采用半手工管理日语词汇学习小程序的方式,所以有必要开发日语词汇…

深度学习--DCGAN

代码之后的注释和GAN的一样,大家如果已经掌握GAN,可以忽略掉哦!!! 在学习DCGAN之前,我们要先掌握GAN,深度学习--生成对抗网络GAN-CSDN博客 这篇博客讲的就是GAN的相关知识,还是很详…

吃掉 N 个橘子的最少天数

代码实现: 方法一:递归——超时 #define min(a, b) ((a) > (b) ? (b) : (a))int minDays(int n) {if (n 1 || n 2) {return n;}if (n % 3 0) {if (n % 2 0) {return min(min(minDays(n - 1), minDays(n / 2)), minDays(n - 2 * (n / 3))) 1;} e…

引擎:主程渲染

一、引擎发展 二、引擎使用 1.游戏渲染流程 2.3D场景编辑器操作与快捷键 3.节点的脚本组件 脚本介绍 引擎执行流程 物体节点、声音组件\物理组件\UI组件、脚本组件 暴露变量到面板 4.节点的查找 基本查找 this.node:挂载当前脚本的节点A; this.nod…

echarts环形图 legend文字过长显示...鼠标移动上展示全称

legend: {type: scroll,orient: vertical,x: left,y: bottom,top: "42%",left: 13%,data: this.dutyNames,textStyle: { color: #fff },triggerEvent: true,tooltip: {show: true,trigger: item,//鼠标移动上去展示全称},formatter: function (params) {var val &qu…

【每日刷题】Day38

【每日刷题】Day38 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 2696. 删除子串后的字符串最小长度 - 力扣(LeetCode) 2. LCR 123. 图书整理…

使用 Spring Boot 配合策略模式增强系统接口扩展能力

使用 Spring Boot 配合策略模式增强系统接口扩展能力 在软件开发中,系统的可扩展性是一个至关重要的方面。而策略模式是一种常见的设计模式,它可以帮助我们实现灵活的算法选择和系统功能扩展。结合 Spring Boot 框架,我们可以更加方便地利用策…

域控操作十四:统一修改域控内计算机用户头像

1,Windows默认头像存储路径,所以我们把这里面的图片都改成自己想要的头像,然后写策略强制使用默认头像就行了 此设置是替换默认头像使用 此设置是为设置默认头像

039——解决室内不能使用GPS问题

目录 引入 GUI整改 client添加GPS分析 完善服务器网络通讯部分代码 添加GPS的BSW层 GPS操作部分代码(相当于驱动) 效果展示 项目管理操作 引入 最近在写论文加上出去玩了一圈所以停更了一段时间。上次咱们GPS有个室内用不了的问题,咱…

本地vite启动的vue项目使用nginx代理

前提: 必须在同一网段或者相同的局域网!!! nginx下载通道: https://nginx.org/en/download.html 步骤: 1、最好下载稳定版本: 2、下载后直接解压(注意:解压后不要放…

C++入门系列-拷贝构造函数

🌈个人主页:羽晨同学 💫个人格言:“成为自己未来的主人~” 拷贝构造函数 概念 在创建对象的时候,能不能创建一个和已知已存在的对象一模一样的对象呢? 拷贝构造函数:只有单个形参,该形参…

【JavaWeb】Day74.Spring——AOP进阶(连接点)

连接点 连接点可以简单理解为可以被AOP控制的方法。我们目标对象当中所有的方法不是都是可以被AOP控制的方法。而在SpringAOP当中,连接点又特指方法的执行。 在Spring中用JoinPoint抽象了连接点,用它可以获得方法执行时的相关信息,如目标类名…