栈与队列经典题目——用队列实现栈

本篇文章讲解栈和队列这一部分知识点的经典题目:用栈实现队列、用队列实现栈。对应的题号分别为:Leetcode.225——用队列实现栈,。

在对两个题目进行解释之前,先回顾以下栈和队列的特点与不同:

栈是一种特殊的线性表,并且只能在尾部进行插入、删除的操作。对于栈的实现,可以通过顺序表或者链表的思路来达成。但是,参考栈只能在尾部进行插入、删除操作的特点。一般采用顺序表进行实现。

队列也是一种特殊的线性表,只能在队尾进行插入操作,在队头进行删除操作。鉴于队列的这一性质,一般采用链表来实现队列。

1.Leetcode.225——用队列实现栈:

题目如下:

1.1 思路分析:

给出下列一个栈:


在栈中,遵从后进先出的原则。但是,本题要求是利用队列来实现栈。对于队列来说,出数据只能从队头进行。题目中要求利用两个队列来实现栈的功能,对于本功能,思路如下:
给定下面两个队列,分别命名为queue1,queue2

按照题目中的要求,需要移除元素4。对于队列来说,移除元素只能从队头进行。所以,先把queue1中的元素1,2,3都移动到queue2中。此时效果如下:

此时,再对queue1进行一次取队头元素的操作即可。 下面为了方便表达,将queue1简称为q1,queue2简称为q2

由上述分析可知。解决本题的关键就是在使用两个队列时,需要让一个队列中存储元素,另一个队列保持为空。当需要进行返回栈顶元素的操作时,再让为空的队列保存另一个队列中的前N-1项元素。所以,q1,q2一个队列用于存储元素,一个用于保持空状态为了方便表达。下面,会默认创建两个结构体指针:empty,来存储q1的地址,noempty来存储q2的地址。并在后续会针对二者谁为空进行判断。

(注:下面只给出各种给定功能的实现方法,在进行解题时,需要预先将编写好的xiami码复制到题目上方,本文采用一起学数据结构(6)——栈和队列_起床写代码啦!的博客-CSDN博客

中的队列) 

1.2 各功能的实现:

 1.2.1 栈的创建及初始化myStackCreate

前面说到,需要一个用于存储元素的队列,一个保持空状态的队列。但是对于二者谁为空,在后续的操作myStackPush中进行判断即可。在本功能中不需要进行判断。代码如下:

//创建队列
typedef struct {Que q1;Que q2;
} MyStack;//初始化队列,注意,返回值返回地址,需要采用malloc返回以保证返回时不会因为变量的局部性成为野指针
MyStack* myStackCreate() {MyStack* obj = (MyStack*)malloc(sizeof(MyStack));QueueInit(&obj->q1);QueueInit(&obj->q2);return obj;
}

1.2.2 向栈中插入元素myStackPush

为了保证empty为空,noempty不为空,所以,在向栈中插入元素时,需要向noempty中插入。在初始化这一步骤中,并没有分辨哪个队列为空,在本步骤并不需要明确知道哪个队列为空,只需要利用QueueEmpty函数判断队列q1,q2是否为空,如果q1为空,此时q1empty,直接向q2中进行插入,反之则向q1中插入,代码如下:

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

1.2.3 移除并返回栈顶元素 myStackPop:

在思路分析中,已经给出了该功能的实现方法。即,让noempty指向的队列中的前N-1项元素移动到empty所对应的元素。在移动元素之前,需要先判断q1,q2哪个队列为空。方法如下:

首先创建结构体指针emptynoempty。让二者分别指向队列q1,q2。利用QueueEmpty函数判断此时的empty是否为空,若为空,则不做改变。若不为空,则令emptynoempty中存储的地址交换。

代码如下:

int myStackPop(MyStack* obj) {Que* noempty = &obj->q1;Que* empty = &obj->q2;if(!QueueEmpty(empty)){noempty = &obj->q2;empty = &obj->q1;} }

再判断出q1,q2哪个队列为empty,哪个队列为noempty后,进行下一步。首先,利用QueueFront函数取出noempty中的队头元素,再利用QueuePush函数将QueueFront取出的元素插入到noempty中。

题目要求,移除并且返回。所以需要额外创建一个变量Top用于存储栈顶元素。之后再利用QueuePop函数移除栈顶元素,最后返回Top即可。代码如下:
 

int myStackPop(MyStack* obj) {Que* noempty = &obj->q1;Que* empty = &obj->q2;if(!QueueEmpty(empty)){noempty = &obj->q2;empty = &obj->q1;}while( QueueSize(noempty) > 1){QueuePush(empty,QueueFront(noempty));QueuePop(noempty);}int Top = QueueFront(noempty);QueuePop(noempty);return Top;}

1.2.4 返回栈顶元素myStackTop

栈顶元素所对应的位置就是队列的队尾。所以,只需要采用向栈中插入元素的方法,通过QueueEmpty函数,对不满足QueueEmpty的队列(即非空队列)调用QueueBack函数,返回函数的返回值即可。代码如下:

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

1.2.5 探空myStackEmpty:

原理较为简单,只给出代码:

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

1.2.6 释放动态开辟的空间myStackFree:
代码如下:

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

2.结果展示及题解代码总览:

2.1 结果展示:


 

2.2 题解代码总览:

typedef int QDataType;
typedef struct QueueNode
{struct QueueNode* next;QDataType data;
}QNode;typedef struct Queue
{QNode* phead;QNode* tail;int size;
}Que;//初始化
void QueueInit(Que* ps);
//销毁
void QueueDestory(Que* ps);
//插入元素
void QueuePush(Que* ps, QDataType x);
//删除元素
void QueuePop(Que* ps);
//取头部元素
QDataType QueueFront(Que* ps);
//取尾部元素
QDataType QueueBack(Que* ps);
//探空
bool QueueEmpty(Que* ps);
//求长度
int QueueSize(Que* ps);void QueueInit(Que* ps)
{assert(ps);ps->phead = ps->tail = 0;ps->size = 0;
}void QueuePush(Que* ps, QDataType x)
{assert(ps);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc");exit(-1);}newnode->next = NULL;newnode->data = x;if (ps->tail == NULL){ps->phead = ps->tail = newnode;}else{ps->tail->next = newnode;ps->tail = newnode;}ps->size++;
}void QueuePop(Que* ps)
{assert(ps);assert(!QueueEmpty(ps));if (ps->phead->next == NULL){free(ps->phead);ps->phead = ps->tail = NULL;}else{QNode* next = ps->phead->next;free(ps->phead);ps->phead = next;}ps->size--;
}QDataType QueueFront(Que* ps)
{assert(ps);assert(!QueueEmpty(ps));return ps->phead->data;
}QDataType QueueBack(Que* ps)
{assert(ps);assert(!QueueEmpty(ps));return ps->tail->data;
}bool QueueEmpty(Que* ps)
{assert(ps);return ps->phead == NULL;
}int QueueSize(Que* ps)
{assert(ps);return ps->size;
}void QueueDestory(Que* ps)
{assert(ps);QNode* cur = ps->phead;while (cur){QNode* next = cur->next;free(cur);cur = next;}ps->phead = ps->tail = NULL;ps->size = 0;
}//创建队列
typedef struct {Que q1;Que q2;
} MyStack;//初始化队列,注意,返回值返回地址,需要采用malloc返回以保证返回时不会因为变量的局部性成为野指针
MyStack* myStackCreate() {MyStack* obj = (MyStack*)malloc(sizeof(MyStack));QueueInit(&obj->q1);QueueInit(&obj->q2);return obj;
}void myStackPush(MyStack* obj, int x) {if(!QueueEmpty(&obj->q1)){QueuePush(&obj->q1,x);}else{QueuePush(&obj->q2,x);}
}//思路:将非空队列中前N-1项元素移到空队列中
int myStackPop(MyStack* obj) {Que* noempty = &obj->q1;Que* empty = &obj->q2;if(!QueueEmpty(empty)){noempty = &obj->q2;empty = &obj->q1;}while( QueueSize(noempty) > 1){QueuePush(empty,QueueFront(noempty));QueuePop(noempty);}int Top = QueueFront(noempty);QueuePop(noempty);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) {QueueDestory(&obj->q1);QueueDestory(&obj->q2);free(obj);
}



 


 

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

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

相关文章

如何隐藏Selenium特征实现自动化网页采集

Selenium是一个流行的自动化网页测试工具,可以通过模拟用户在Chrome浏览器中的操作来完成网站的测试。然而,有些网站会检测浏览器是否由Selenium驱动,如果是,就会返回错误的结果或拒绝访问。为了避免这种情况,我们需要…

网络安全进阶学习第十六课——业务逻辑漏洞介绍

文章目录 一、什么是业务逻辑二、业务逻辑漏洞的成因三、逻辑漏洞的重要性四、业务逻辑漏洞分类五、业务逻辑漏洞——业务授权安全1、未授权访问2、越权访问1) 平行越权(水平越权是指相同权限的不同用户可以互相访问)2) 垂直越权(垂直越权是指…

蓝桥杯 题库 简单 每日十题 day1

01 空间 本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。 小蓝准备用 256MB 的内存空间开一个数组,数组的每个元素都是 32 位 二进制整数,如果不考虑程序占用的空间和维护内存需要的辅助空间&#xff…

免费开箱即用微鳄OA办公系统

编者按:本文介绍基于天翎低代码平台实现的微鳄OA办公系统功能,免费开箱即用。支持私有化部署,同时提供天翎开发后台,企业可按需求可灵活调整配置。 OA办公系统可以提高企业的效率、降低成本、增强管理能力和灵活性,同时…

华为云云耀云服务器L实例评测|华为云云耀云服务器L实例开展性能评测

作者简介: 辭七七,目前大二,正在学习C/C,Java,Python等 作者主页: 七七的个人主页 文章收录专栏: 七七的闲谈 欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖&#x1f…

element-ui tree组件实现在线增删改

这里要实现一个tree 增删改 <!--oracle巡检项--> <template><div class"oracle_instanceType"><el-row type"flex" align"middle" justify"space-between"><iclass"el-icon-s-fold iBox"click&q…

笔记1.1 计算机网络基本概念

计算机网络是通信技术与计算机技术紧密结合的产物 通信系统模型&#xff1a; 计算机网络是一种通信网络 计算机网络是互连的、自洽的计算机集合。 互连&#xff1a;互联互通 自洽&#xff1a;无主从关系 通过交换网络互连主机 Internet&#xff1a;数以百万计的互连的计算设…

webpack-cl明明已经安装了,但是还是会报未安装

解决办法&#xff1a;对当前项目目录进行安装 npm install webpack webpack-cli --save-dev

腾讯mini项目-【指标监控服务重构】2023-08-06

今日已办 feature/client_traces_profile 修改 consumer 4个阶段的 spankind将 profile 的 span 作为 root span&#xff0c;保持与 venus 的 follows from 的 link feature/profile-otelclient-metric 将 metric 部分使用新分支 push go.opentelemetry.io/otel/propagatio…

记一次在amd架构打包arm64架构的镜像的试错经历

前提 在amd架构打包了一个镜像&#xff0c;放在arm64架构服务器上可以load ,但是run的时候报平台不兼容的问题。 运行如下命令查看发现 架构属于 amd64 如下&#xff1a; docker inspect 镜像ID需要生成一个arm的镜像才能运行。 尝试 首先Dockerfile 的FROM 基础镜像就的是…

I/O多路复用三种实现

一.select 实现 &#xff08;1&#xff09;select流程 基本流程是&#xff1a; 1. 先构造一张有关文件描述符的表; fd_set readfds 2. 清空表 FD_ZERO() 3. 将你关心的文件描述符加入到这…

LeetCode-热题100-笔记-day29

199. 二叉树的右视图https://leetcode.cn/problems/binary-tree-right-side-view/ 给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 示例 1: 输入: [1,2,3,null,5,null,4] 输出: [1…

OpenGL ES视频特效开发参考Shadertoy参数详解参考Godot文档

今天一个大厂的学员过来问shadertoy上一些参数的问题&#xff0c;因为我之前用过一段时间Godot引擎&#xff0c; 我清晰记得Godot官方文档有明确的解释&#xff0c;所以整理下发给做特效的同学。 Shadertoy是一个网站&#xff0c;它方便用户编写片段着色器并创造出纯粹的魔法。…

网站排名下降的原因和解决方法(SEO优化失误可能导致网站排名下降)

SEO优化是网站推广的重要环节&#xff0c;它可以提升网站的访问量和排名。但是&#xff0c;SEO优化不当也可能会导致网站排名下降。本文将分析SEO优化失误可能导致网站排名下降的原因&#xff0c;并提供相应的解决方法。 一&#xff1a;标题——SEO优化过度 SEO优化的目的是为…

数据结构与算法--排序算法复习

目录 1.三种常见的简单排序&#xff1a; 1.1冒泡排序 1.2 选择排序 1.3 插⼊排序 2 常见高级排序算法 2.1 希尔排序 2.2 快速排序 2.3 归并排序 2.4计数排序 先上结论&#xff1a; 1.三种常见的简单排序&#xff1a; 1.1冒泡排序 1.⾸先在未排序数组的⾸位开始&#…

spring_javaConfig实现配置

现在我们尝试不使用Spring的XML文件来配置了&#xff0c;全权交给Java来做 1 编写pojo类 这个类要被Spring接管&#xff0c;要被注册到容器中 添加Component注解通过Value注解来为属性注入值 package com.wq.pojo;import org.springframework.beans.factory.annotation.Value…

利用芯片74hc165为单片机增加输入扩展端口proteus仿真arduino

我们前面的博文《输入端口少如何扩展&#xff1f;74hc148或74ls148级联在arduino中实现16转4的应用》介绍了148,148输入后可以立即输出到数码管&#xff0c;可以说它是自带编BCD编码器的。而今天这里我们主要介绍的74hc165是没有编码器&#xff0c;这里我们以proteus为仿真环境…

CMake高级用法实例分析(学习paddle官方的CMakeLists)

cmake基础学习教程 https://juejin.cn/post/6844903557183832078 官方完整CMakeLists cmake_minimum_required(VERSION 3.0) project(PaddleObjectDetector CXX C)option(WITH_MKL "Compile demo with MKL/OpenBlas support,defaultuseMKL." ON) o…

GaussDB(DWS)云原生数仓技术解析:湖仓一体,体验与大数据互联互通

文章目录 前言一、关于数据仓库需求场景分类二、数据仓库线下部署场景2.1、线下部署场景介绍及优劣势说明2.2、线下部署场景对应的客户需求 三、数据仓库公有云部署场景3.1、公有云部署场景介绍及优劣势说明3.2、公有云部署场景对应的客户需求 四、为何重视数据共享&#xff08…

postgresql-视图

postgresql-视图 视图概述使用视图的好处 创建视图修改视图删除视图递归视图可更新视图WITH CHECK OPTION 视图概述 视图&#xff08;View&#xff09;本质上是一个存储在数据库中的查询语句。视图本身不包含数据&#xff0c;也被称为 虚拟表。我们在创建视图时给它指定了一个…