Leetcode刷题之用队列实现栈(C语言版)

Leetcode刷题之用队列实现栈(C语言版)

  • 一、题目描述
  • 二、题目要求
  • 三、题目示例
  • 四、题目解析
    • Ⅰ、MyStack* myStackCreate
    • Ⅱ、void myStackPush(MyStack* obj, int x)
    • Ⅲ、int myStackPop(MyStack* obj)
    • Ⅳ、int myStackTop(MyStack* obj)
    • Ⅴ、bool myStackEmpty(MyStack* obj)
    • Ⅵ、void myStackFree(MyStack* obj)
  • 五、完整代码

225、用队列实现栈

一、题目描述

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。实现 MyStack 类:①、void push(int x) 将元素 x 压入栈顶。
②、nt pop() 移除并返回栈顶元素。
③、int top() 返回栈顶元素。
④、boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

二、题目要求

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

三、题目示例

在这里插入图片描述

四、题目解析

首先我们看到本题是用队列实现栈。那么我们便要对栈和队列的相关特性有一定的了解,例如栈是先进后出的,而队列是先进先出的。如果有伙伴对这两种数据结构有些遗忘的话,建议看一下博主之前的两篇文章,分别是《数据结构——栈的详细介绍》和《数据结构——看完这篇保证你学会队列》。
我们想要解决这道题,首先便要实现一个完整的队列,其中的接口包括初始化队列,销毁队列,入队,出队等,其代码如下:
在这里插入图片描述

//定义数据类型
typedef int QueueDataType;
//定义队列结构
typedef struct QueueNode
{struct QueueNode* next;QueueDataType Data;
}Qnode;//定义头、尾指针
typedef struct Queue
{Qnode* phead;Qnode* ptail;int size;
}Queue;//初始化
void InitQueue(Queue* pq);
//销毁
void DestoryQueue(Queue* pq);
//入队
void PushQueue(Queue* pq, QueueDataType x);
//出队
void PopQueue(Queue* pq);
//判空
bool QueueEmpty(Queue* pq);
//获取SIze
int SizeQueue(Queue* pq);
//获取队头元素
QueueDataType QueueFront(Queue* pq);
//获取队尾元素
QueueDataType QueueBack(Queue* pq);void InitQueue(Queue* pq)
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}
//销毁
void DestoryQueue(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 PushQueue(Queue* pq, QueueDataType x)
{assert(pq);Qnode* newnode = (Qnode*)malloc(sizeof(Qnode));if (newnode == NULL){perror("malloc fail");return;}//赋值newnode->Data = x;newnode->next = NULL;//分情况讨论if (pq->ptail == NULL){assert(pq->phead == NULL);pq->phead = pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}
//出队
void PopQueue(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));//一个节点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--;}
//判空
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->size == 0;
}
//获取SIze
int SizeQueue(Queue* pq)
{assert(pq);return pq->size;
}
//获取队头元素
QueueDataType QueueFront(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->phead->Data;
}
//获取队尾元素
QueueDataType QueueBack(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->ptail->Data;
}

构建好队列的各种接口之后,我们需要在Mystack的结构体中创建两个队列变量。代码如下:

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

Ⅰ、MyStack* myStackCreate

该接口,需要我们在内存中开辟空间,利用malloc函数,并且将q1和q2进行初始化。

MyStack* myStackCreate() 
{MyStack*obj=(MyStack*)malloc(sizeof(MyStack));if(obj==NULL){perror("malloc fail");return NULL;}InitQueue(&obj->q1);InitQueue(&obj->q2);return obj;}

Ⅱ、void myStackPush(MyStack* obj, int x)

如果两个队列都为空,那么任选一个进行入队操作即可,后续入队往有数据的队列进行入队操作即可。

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

Ⅲ、int myStackPop(MyStack* obj)

最为复杂的便是出栈了,我们的大体思路便是假定q1为空,q2不为空:如果结果相反,则调换一下二者的顺序,我们将不为空的队列进行出队操作,并将其数据压入为空的队列,直到为空的队列中只剩下一个数据,我们将这个数据定义为top,并对其进行出队操作,最后将其进行返回。

 Queue*EmptyQ=&obj->q1;Queue*NonEmptyq=&obj->q2;if(!QueueEmpty(&obj->q1)){EmptyQ=&obj->q2;NonEmptyq=&obj->q1;}while(SizeQueue(NonEmptyq)>1){PushQueue(EmptyQ,QueueFront(NonEmptyq));PopQueue(NonEmptyq);}int top=QueueFront(NonEmptyq);PopQueue(NonEmptyq);return top;

Ⅳ、int myStackTop(MyStack* obj)

解决这个接口,我们首先需要找到不为空的那个队列,然后调用其获取队尾数据的函数,最后将这个函数返回的结果返回即可。

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

Ⅴ、bool myStackEmpty(MyStack* obj)

我们需要保证我们的两个队列都为空,这样才能够保证我们创建的队列为空。

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

Ⅵ、void myStackFree(MyStack* obj)

需要先对我们所创建的q1和q2队列进行销毁,然后再对ob进行free操作,以防止内存的泄漏。

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

五、完整代码

//定义数据类型
typedef int QueueDataType;
//定义队列结构
typedef struct QueueNode
{struct QueueNode* next;QueueDataType Data;
}Qnode;//定义头、尾指针
typedef struct Queue
{Qnode* phead;Qnode* ptail;int size;
}Queue;//初始化
void InitQueue(Queue* pq);
//销毁
void DestoryQueue(Queue* pq);
//入队
void PushQueue(Queue* pq, QueueDataType x);
//出队
void PopQueue(Queue* pq);
//判空
bool QueueEmpty(Queue* pq);
//获取SIze
int SizeQueue(Queue* pq);
//获取队头元素
QueueDataType QueueFront(Queue* pq);
//获取队尾元素
QueueDataType QueueBack(Queue* pq);void InitQueue(Queue* pq)
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}
//销毁
void DestoryQueue(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 PushQueue(Queue* pq, QueueDataType x)
{assert(pq);Qnode* newnode = (Qnode*)malloc(sizeof(Qnode));if (newnode == NULL){perror("malloc fail");return;}//赋值newnode->Data = x;newnode->next = NULL;//分情况讨论if (pq->ptail == NULL){assert(pq->phead == NULL);pq->phead = pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}
//出队
void PopQueue(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));//一个节点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--;}
//判空
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->size == 0;
}
//获取SIze
int SizeQueue(Queue* pq)
{assert(pq);return pq->size;
}
//获取队头元素
QueueDataType QueueFront(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->phead->Data;
}
//获取队尾元素
QueueDataType QueueBack(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->ptail->Data;
}typedef struct 
{Queue q1;Queue q2;
} MyStack;MyStack* myStackCreate() 
{MyStack*obj=(MyStack*)malloc(sizeof(MyStack));if(obj==NULL){perror("malloc fail");return NULL;}InitQueue(&obj->q1);InitQueue(&obj->q2);return obj;}void myStackPush(MyStack* obj, int x) 
{if(!QueueEmpty(&obj->q1)){PushQueue(&obj->q1,x);}else{PushQueue(&obj->q2,x);}
}int myStackPop(MyStack* obj)
{Queue*EmptyQ=&obj->q1;Queue*NonEmptyq=&obj->q2;if(!QueueEmpty(&obj->q1)){EmptyQ=&obj->q2;NonEmptyq=&obj->q1;}while(SizeQueue(NonEmptyq)>1){PushQueue(EmptyQ,QueueFront(NonEmptyq));PopQueue(NonEmptyq);}int top=QueueFront(NonEmptyq);PopQueue(NonEmptyq);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) 
{DestoryQueue(&obj->q1);DestoryQueue(&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);
*/

在这里插入图片描述

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

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

相关文章

文件夹重命名:彻底摆脱数字困扰,批量修改文件夹名去除数字

在日常生活和工作中,经常会遇到需要修改文件夹名称的情况。有时候是因为文件夹名称中包含了数字,有时候是因为文件夹名称不符合规范。无论出于什么原因,修改文件夹名称都是一件非常繁琐的事情。尤其是需要修改大量文件夹名称时,手…

Jenkins 整合 Docker 自动化部署

Docker 安装 Jenkins 配置自动化部署 1. Docker 安装 Jenkins 1.1 拉取镜像文件 docker pull jenkins/jenkins1.2 创建挂载文件目录 mkdir -p $HOME/jenkins_home1.3 启动容器 docker run -d -p 8080:8080 -v $HOME/jenkins_home:/var/jenkins_home --name jenkins jenkin…

k8s部署的java服务查看连接nacos缓存的配置文件

一、问题描述 k8s部署的java服务,使用nacos中的配置文件,需要在缓存中查看该服务具体是使用到了哪些配置文件 二、解决 参考文档: https://nacos.io/zh-cn/docs/system-configurations.html 文档描述如下: 进入java服务容器进入用户目录下的nacos&a…

Java枚举详解

一、什么是枚举类型 枚举类型是一种特殊的数据类型,用于定义一组固定的命名常量。枚举类型提供了一种更强大、更安全和更易读的方式来表示一组相关的常量。 在Java中,枚举类型是通过使用enum关键字来定义的。枚举类型可以包含一个或多个枚举常量&#xf…

vue005——vue组件入门(非单文件组件和单文件组件)

一、非单文件组件 1.1、单文件组件的使用 1.1.1、局部注册 1、第一步&#xff1a;创建school组件 2、第二步&#xff1a;注册组件&#xff08;局部注册&#xff09; 3、第三步&#xff1a;使用组件&#xff08;编写组件标签&#xff09; <!DOCTYPE html> <html>…

设计模式—里氏替换原则

1.概念 里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说&#xff0c;任何基类可以出现的地方&#xff0c;子类一定可以出现。 LSP是继承复用的基石&#xff0c;只有当衍生类可以替换掉基类&#xff0c;软件单位的功能不受到影…

Mac Ubuntu双系统解决WiFi和WiFi 5G网络不可用问题

文章目录 设备信息1. Ubuntu WiFi不可用解决方式查看Mac的网卡型号根据网卡型号搜索获取到的解决方法查看WiFi名字问题参考链接 2. 解决WiFi重启后失效问题打开终端创建.sh脚本文件编辑脚本文件复制粘贴脚本修改脚本权限创建并编辑systemd service文件复制粘贴下文到systemd se…

只考数据结构,计算机评级C+,成都信息工程大学考情分析

成都信息工程大学(C) 考研难度&#xff08;☆☆&#xff09; 内容&#xff1a;23考情概况&#xff08;拟录取和复试分析&#xff09;、院校概况、24专业目录、23复试详情、各专业考情分析、各科目考情分析。 正文1715字&#xff0c;预计阅读&#xff1a;3分钟 2023考情概况 …

Java实现求最大值

1 问题 接收用户输入的3个整数&#xff0c;如何将最大值作为结果输出。 2 方法 采用“截图文字代码”的方式描述。 引入输入包调用main()函数&#xff0c;提示并接收用户输入的3个整数&#xff0c;并交由变量a b c来保存。对接收的3个数据进行比较&#xff0c;先比较a和b&#…

原型 原型对象 原型链

在面向开发对象开发过程中对每一个实例添加方法&#xff0c;会使每一个对象都存在该添加方法造成空间浪费 通过对原型添加公共的属性或方法&#xff0c;使所有实例对象都可访问 原型为了共享公共的成员 prototype 原型: JS为每个构造函数提供一个属性prototype(原型),它的值…

深眸科技聚焦AI机器视觉检测,驱动3C电子行业集成创新实现新需求

随着消费的升级及国家政策的助推&#xff0c;国内3C电子市场不断扩大&#xff0c;行业实现高速发展。近年来&#xff0c;3C电子产品持续迭代&#xff0c;生产工艺也逐渐复杂化&#xff0c;相关生产线定位组装、零部件检测、整机产品检测等环节&#xff0c;亟需使用具备较强适应…

举个栗子!Quick BI 技巧(4):创建面积图

面积图又叫区域图&#xff0c;是在折线图的基础之上形成的, 它将折线图中折线与自变量坐标轴之间的区域使用颜色或者纹理填充&#xff0c;这样一个填充区域我们叫做面积&#xff0c;颜色的填充也可以更好的突出趋势信息。 有数据粉好奇如何使用 Quick BI 来制作面积图&#xf…

NVMe-oF E-JBOF设计解析:WD RapidFlex网卡、OpenFlex Data24

OpenFlex Data24 NVMe-oF Storage Platform WD的SN840 NVMeSSD新品并没有太吸引我注意&#xff0c;因为它还是PCIe 3.0接口的&#xff0c;要知道Intel的PCIe 4.0 SSD都已经推出了。 但上面这个NVMe-oF&#xff08;NVMe over Fabric&#xff09;EBOF&#xff08;区别于普通JBO…

css三角,鼠标样式,溢出文字

目录 css三角 鼠标样式 例子&#xff1a;页码模块 溢出文字表示方式 margin负值运用 css三角强化 css三角 css三角中&#xff1a;line-height&#xff1a;0和font-size&#xff1a;0是防止兼容性的问题 jd {position: relative;width: 120px;height: 249px;background-…

在 Ubuntu 上安装最新版的 Calibre

目录 前言 方法1&#xff1a;从 Ubuntu 的仓库安装 Calibre 卸载 Calibre 方法2&#xff1a;获取最新版本的 Calibre 卸载 Calibre 结语 前言 Calibre 是一款自由开源的电子书软件。下面介绍如何在 Ubuntu Linux 上安装它。 作为电子书管理的瑞士军刀&#xff0c;Calibre …

线程-Thread类及常见方法

目录 一、创建线程 1.继承 Thread 类 2. 实现 Runnable 接口 3.匿名内部类创建 Thread 子类对象 4. 匿名内部类创建 Runnable 子类对象 5. lambda 表达式创建 Runnable 子类对象 二、Thread 类及常见方法 2.1 Thread 的常见构造方法 2.2 Thread 的几个常见属性 2.3 启…

C++初级项目webserver项目流程介绍(2)

一、引言 C的webserver项目是自己在学完网络编程后根据网课的内容做的一个初级的网络编程项目。 这个项目的效果是可以在浏览器通过输入网络IP地址和端口&#xff0c;然后打开对应的文件目录 效果如下&#xff1a; 也可以打开文件夹后点击目录&#xff0c;打开到对应的文件夹…

ES之x-pack-core-7.14.2许可证修改为白金版

X-Pack是什么 X-pack是elasticsearch的一个扩展包&#xff0c;将安全&#xff0c;警告&#xff0c;监视&#xff0c;图形和报告功能捆绑在一个易于安装的软件包中&#xff0c;虽然x-pack被设计为一个无缝的工作&#xff0c;但是你可以轻松的启用或者关闭一些功能。 主要分一下步…

WebSocket 鉴权策略与技巧详解

WebSocket 作为实时通信的利器&#xff0c;越来越受到开发者的青睐。然而&#xff0c;为了确保通信的安全性和合法性&#xff0c;鉴权成为不可或缺的一环。本文将深入探讨 WebSocket 的鉴权机制&#xff0c;为你呈现一揽子的解决方案&#xff0c;确保你的 WebSocket 通信得心应…

【Qt之QTextDocument】使用及表格显示富文本解决方案

【Qt之QTextDocument】使用 描述常用方法及示例使用QTextList使用QTextBlock使用QTextTable表格显示富文本结论 描述 QTextDocument类保存格式化的文本。 QTextDocument是结构化富文本文档的容器&#xff0c;支持样式文本和各种文档元素&#xff0c;如列表、表格、框架和图像。…