[数据结构高频面试题]用两个栈实现队列详解

news/2024/5/4 10:17:55/文章来源:https://blog.csdn.net/weixin_67596609/article/details/129710078

文章目录

一、栈实现队列的特点分析

1、1 具体分析

1、2 整体概括

二、用栈模拟队列代码的实现

2、1 手撕 栈 代码

2、1、1 stack.h

2、1、2 stack.c

2、2 用栈实现队列代码


🙋‍♂️ 作者:@Ggggggtm 🙋‍♂️

👀 专栏:数据结构与算法、高频面试问题 👀

💥 标题:用栈模拟队列 💥

 ❣️ 寄语:与其忙着诉苦,不如低头赶路,奋路前行,终将遇到一番好风景 ❣️

  在数据结构中,栈和队列是较为常见的两种数据结构。他们各有自己的特点:栈是后进先出原则,队列是先进先出原则。那怎么用栈去实现队列呢?此问题在面试中也是高频出现的问题。本篇文章会给出详细解释。

一、栈实现队列的特点分析

1、1 具体分析

  队列和栈在插入数据时,队列是从队尾进行插入栈是从栈顶插入。但是他们的删除数据是不同的。我们知道队列的特点是:先新先出 ,删除数据是在对头进行删除,栈的特点是:先进后出,也就是在栈顶进行删除。

  当我们用栈实现队列时,最根本的也是最重要的是需要解决删除的问题。我们用栈实现队列时,在栈中的删除就不是删除栈顶的元素了,我们需要根据队列的特点进行删除,也就是我们需要删除的是栈底的元素  怎么删除栈底的元素呢?在这里我们需要两个栈,分别命名为push栈pop栈。我们先把元素的插入全部插入到push栈中,当需要删除时,我们首先把push栈中的元素全部导入到pop栈中,此时的pop栈中的栈顶元素,相当于我们要删除的对头元素了。

  那如果我们想要接着插入呢?我们接着往push栈中插入即可。删除的话我们看pop栈中是否有元素,如果pop栈不为空,就接着删除如果pop栈为空,我们需要把push栈的元素再次导入到pop栈中删除即可。具体流程我们可以结合下图(gif)理解: 

1、2 整体概括

  用栈模拟队列我们整体的思路分为以下几步:

  • 我们需要先定义两个栈,分别为push栈和pop栈;
  • 插入数据到往push栈中;
  • 删除数据时,需要先判断pop栈是否为空。如果为空,需要将push栈的所有数据导入到pop栈中。如果不为空,就直接在pop栈删除即可。
  • 再插入数据时,就往push栈中插入即可。

  以上即为用栈模拟队列的全过程,那我们来看代码的实现。

二、用栈模拟队列代码的实现

  这里我们用c语言进行实现。所以我们这里需要先手撕出一个栈。

2、1 手撕 栈 代码

2、1、1 stack.h

#define INT_CAPACITY 4
typedef int STDataType;typedef struct stack
{STDataType* a;int top;int capacity;
}ST;void STInit(ST* ps);
void STDestory(ST* ps);bool STIsEmpty(ST* ps);
void STPush(ST* ps, STDataType x);
void STPop(ST* ps);
int STSize(ST* ps);STDataType STTop(ST* ps);

2、1、2 stack.c

void STInit(ST* ps)
{assert(ps);ps->a = (STDataType*)malloc(sizeof(STDataType)* INT_CAPACITY);if (ps->a == NULL){perror("malloc fail");exit(-1);}ps->top = 0;ps->capacity = INT_CAPACITY;
}
void STDestory(ST* ps)
{assert(ps);free(ps->a);ps->capacity = 0;ps->top = 0;
}bool STIsEmpty(ST* ps)
{assert(ps);return ps->top==0;
}
void STPush(ST* ps, STDataType x)
{assert(ps);if (ps->top == ps->capacity){STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * ps->capacity * 2);if (tmp == NULL){perror("realloc fail");exit(-1);}ps->a = tmp;ps->capacity *= 2;}ps->a[ps->top++] = x;
}
void STPop(ST* ps)
{assert(ps);assert(!STIsEmpty(ps));ps->top--;
}
int STSize(ST* ps)
{assert(ps);return ps->top;}STDataType STTop(ST* ps)
{assert(ps);assert(!STIsEmpty(ps));return ps->a[ps->top - 1];
}

2、2 用栈实现队列代码

这个是OJ链接( 用栈实现队列 - OJ链接(力扣)),大家可以直接点开链接用其他语言做一下。我们看C语言的代码实现。

#define INT_CAPACITY 4
typedef int STDataType;typedef struct stack
{STDataType* a;int top;int capacity;
}ST;void STInit(ST* ps);
void STDestory(ST* ps);bool STIsEmpty(ST* ps);
void STPush(ST* ps, STDataType x);
void STPop(ST* ps);
int STSize(ST* ps);STDataType STTop(ST* ps);void STInit(ST* ps)
{assert(ps);ps->a = (STDataType*)malloc(sizeof(STDataType)* INT_CAPACITY);if (ps->a == NULL){perror("malloc fail");exit(-1);}ps->top = 0;ps->capacity = INT_CAPACITY;
}
void STDestory(ST* ps)
{assert(ps);free(ps->a);ps->capacity = 0;ps->top = 0;
}bool STIsEmpty(ST* ps)
{assert(ps);return ps->top==0;
}
void STPush(ST* ps, STDataType x)
{assert(ps);if (ps->top == ps->capacity){STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * ps->capacity * 2);if (tmp == NULL){perror("realloc fail");exit(-1);}ps->a = tmp;ps->capacity *= 2;}ps->a[ps->top++] = x;
}
void STPop(ST* ps)
{assert(ps);assert(!STIsEmpty(ps));ps->top--;
}
int STSize(ST* ps)
{assert(ps);return ps->top;}STDataType STTop(ST* ps)
{assert(ps);assert(!STIsEmpty(ps));return ps->a[ps->top - 1];
}typedef struct 
{ST StackPop;ST StackPush;
} MyQueue;MyQueue* myQueueCreate()
{MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));STInit(&obj->StackPop);STInit(&obj->StackPush);return obj;
}void myQueuePush(MyQueue* obj, int x) 
{STPush(&obj->StackPush,x);
}int myQueuePeek(MyQueue* obj) 
{if(STSize(&obj->StackPop)==0){while(STSize(&obj->StackPush)!=0){STPush(&obj->StackPop,STTop(&obj->StackPush));STPop(&obj->StackPush);}}return STTop(&obj->StackPop);
}int myQueuePop(MyQueue* obj) 
{int ret=myQueuePeek(obj);STPop(&obj->StackPop);return ret;
}bool myQueueEmpty(MyQueue* obj) 
{return STSize(&obj->StackPop)==0 && STSize(&obj->StackPush)==0;
}void myQueueFree(MyQueue* obj) 
{STDestory(&obj->StackPop);STDestory(&obj->StackPush);free(obj);
}

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

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

相关文章

Flink- 物理分区、Sink输出

物理分区 随机分区(shuffle) 轮询分区(Round-Robin) 重缩放分区(rescale) 广播(broadcast) 全局分区(global) 自定义分区(Custom) …

Studio One6中文语言版DAW数字音频音乐创作软件

Studio One6是一款非常实用的数字音乐创作软件,专门用于创作现代化音乐,软件具有简洁的界面和强大的功能,能够很好地辅助用户创作音乐。顾名思义就是“一个工作室”的意思,它所倡导的制作理念是直接在一个制作软件里完成音乐制作的…

Android 解包payload.bin文件,获取system.img

解析payload.bin获取.img文件 payload.bin payload.bin是Android OTA镜像打包文件,将包括system.img、boot.img和lk.img等在内的Android系统进行,打包为一个payload.bin文件。 在系统OTA过程中,系统会自动解压安装。 前期准备 需要安装py…

学习Java日志框架之——搞懂日志门面(JCL+SLF4J)

文章目录一、什么是日志门面1、门面模式(外观模式)2、日志门面二、了解JCL1、JCL组件结构2、JCL案例(1)JCL默认实现(2)导入log4j测试原有程序三、SLF4J简介四、SLF4J基本使用1、入门案例2、动态打印信息3、…

一次内存泄露排查

前因: 因为测试 长时间压测导致 接口反应越来越慢,甚至 导致服务器 崩溃 排查过程 1、top 查看是 哪个进程 占用 内存过高 2、根据 进程 id 去查找 具体是哪个 程序的问题 ps -ef| grep 41356 可以看到 具体的 容器位置 排查该进程 对象存活 状态…

23年PMP考试会使用第七版教材吗?

大家都知道了,今年的考纲是改版了的,为啥要改版呢,因为《PMBOK指南》更新到第七版了,考纲自然也要更新,据PMI的市场调查,近年来,项目管理行业新趋势在第六版和旧考纲中未收纳,为了确…

三、数据链路层

(一)纠错与检错1、奇偶校验码(再研究下,原理知道,具体过程无法重现)分为奇校验和偶校验,奇偶校验位在首部或尾部,奇偶校验满信息位奇偶校验位(1)原理&#xf…

Redis 数据结构

这里写目录标题Redis 数据结构一、String类型String数据类型的使用场景key 的设置约定二、Hash数据类型string存储对象(json)与hash存储对象的区别三、list 类型四、set 类型set数据交并差操作set 类型数据操作的注意事项六、sorted_set 类型Redis 数据结…

算法----火柴拼正方形

题目 你将得到一个整数数组 matchsticks ,其中 matchsticks[i] 是第 i 个火柴棒的长度。你要用 所有的火柴棍 拼成一个正方形。你 不能折断 任何一根火柴棒,但你可以把它们连在一起,而且每根火柴棒必须 使用一次 。 如果你能使这个正方形&a…

Junit单元测试框架

1)Junit是一个开源的JAVA语言的单元测试框架,也是JAVA方向使用最广泛的单元测试框架,使用JAVA开发者都应该学习junit框架,并且掌握单元测试的编写 2)selenium和Junit都可以被导入到maven项目里面 3)先进行创建maven项目,导入相关依…

linux 全局环境变量删除后 还有 仍然存在

linux 全局环境变量删除后 还有 仍然存在1、编辑 /etc/profile2、设置REDISCLI_AUTH后,redis-cli 进去redis后不需要再次认证2、删除全局环境后 source后 仍然存在3、unset释放全局环境变量4、总结1、编辑 /etc/profile 设置redis环境变量 在末尾加入一行 export R…

家电企业数字工厂系统解决方案

国内小型家电生产商的中小企业普遍使用传统的手工作业模式,依靠大量的人力,线下管理各种数据,如:纸质文档、excel制作等,信息化程度非常低,严重限制着企业生产效率的提升和生产规模的扩大。对传统制造企业来…

基于WEB的网上购物系统的设计与实现(附:源码 论文 sql文件)

摘 要 随着计算机网络技术的飞速发展和人们生活节奏的不断加快,电子商务技术已经逐渐融入了人们的日常生活当中,网上商城作为电子商务最普遍的一种形式,已被大众逐渐接受。因此开发一个网上商城系统,适合当今形势,更加…

AWS白皮书 – 成本优化

本文讲解AWS良好架构框架(AWS Well-Architected Framework)里其中五大支柱之一:成本优化(Cost Optimization)。 一套成本优化型系统应充分利用全部资源、以最低价格来实现业务成果,同时充分满足你的功能需…

Google Bard VS ChatGPT:哪个是更好的AI聊天机器人?

文章目录前言一、Bard和ChatGPT的宏观对比二、应用场景不同三、知识的时效性四、未来的归宿总结前言 自从 OpenAI 向公众发布ChatGPT以来的过去几个月里,我们都见证了围绕 ChatGPT 的各种测评,并为它带来的效果感到惊艳。 昨晚Google开放了自家研发的A…

SpringBoot的简介和使用

文章目录1. SpringBoot简介和概述2. SpringBoot的使用3.SpringBoot 项目打包及运行4.切换web服务器1. SpringBoot简介和概述 Spring Boot是由Pivotal团队提供的一套开源框架,可以简化spring应用的创建及部署。它提供了丰富的Spring模块化支持,可以帮助开…

JUC并发编程共享模型之不可变(五)

5.1 问题引出 public interface Account {// 获取余额Integer getBalance();void withdraw(Integer amount);/*** 方法内会启动1000个线程&#xff0c;每个线程做-10元的操作* 如果初始余额为 10000 那么正确的结果应当是0*/static void demo(Account account){List<Thread…

整数拼接(思维枚举,两变量满足某条件-->通过其中一变量根据条件推断另一变量

2068.整数拼接&#xff08;思维&#xff0c;枚举&#xff09; 输入样例&#xff1a; 4 2 1 2 3 4输出样例&#xff1a; 6大佬思路 很多需要双重循环两个值&#xff0c;暴力判断组合在一起是否满足某个条件(比如等式是否成立)&#xff0c; 其实可以换个角度&#xff0c;遍历…

WPF中阴影效果和模糊效果的使用

总目录 文章目录总目录前言一、DropShadowEffect1、DropShadowEffect各属性效果图2、实现代码二、BlurEffect1、BlurEffect各属性效果图2、实现代码3、进阶使用结语前言 WPF中的控件效果主要通过Effect来实现&#xff0c;而Effect有DropShadowEffect&#xff08;投影效果&…

【并发】详解redis的incr、decr命令

一、前言 redis是一个单线程的服务&#xff0c;那么所有的命令肯定会排队被redis执行&#xff0c;redis提供的命令都是原子性的&#xff0c;百度搜索incr\decr就是说将对应的key1&#xff0c;key-1的值重新set到redis中&#xff0c;而且很多都是认为incr\decr原子性的&#xf…