速学数据结构 | 我不允许还有人不会用栈实现队列!

2023-11-06 19:36

本文主要是介绍速学数据结构 | 我不允许还有人不会用栈实现队列!,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


在这里插入图片描述

🎬 鸽芷咕:个人主页

 🔥个人专栏:《Linux深造日志》《C++干货基地》

⛺️生活的理想,就是为了理想的生活!

📋 前言

  🌈hello! 各位铁铁们大家好啊,不知道大家对栈和队列的学习都学过了吧?那么用栈来实现队列你会做嘛?
  ⛳️栈和队列我们前面说了都是一种特殊的线性表,而在学习过程中用栈来尝试实现队列是很有必要来考验一下我们对栈和队列的掌握的!
  📚本期文章收录在《数据结构&算法》,大家有兴趣可以看看呐
  ⛺️ 欢迎铁汁们 ✔️ 点赞 👍 收藏 ⭐留言 📝!

文章目录

  • 📋 前言
  • 一、 栈实现队列具体要求
  • 二、栈实现队列的核心思想
    • 2.1 如何插入的思想
    • 2.2 如何插入呢?
  • 三、栈实现队列的代码实现
      • 3.1 栈实现队列的初始化
      • 3.2 栈实现队列判空
      • 3.3 栈实现队列的插入
      • 3.4 栈实现队列删除
      • 3.5 栈实现队列的头元素
      • 3.6 栈实现队列的销毁
  • 四、栈实现队列的成果检验
  • 📝全篇总结

一、 栈实现队列具体要求

在这里插入图片描述

二、栈实现队列的核心思想

  • 栈和队列一个后进先出一个先进先出先先在下图看一下我们的区别:

在这里插入图片描述

2.1 如何插入的思想

栈的特点是后进先出而我们要实现的队列是先进先出,诶这刚好和队列的特点相反:

  • 那么我们使用俩个栈
  • 一个用来插入数据
  • 一个用来把插入的数据翻转一下就不可以实现 先进先出的特点 了?

在这里插入图片描述

2.2 如何插入呢?

前面说了使用俩个栈来解决队列先进先出的问题,其核心思想就是

  • 一个栈来当 push 栈存放数据
  • 一个栈用来pop数据

那么具体的核心思想是什么?其实只需要把push的 翻转一下然后插入到pop 栈中就好了,这样我们就可以的到一个理论上先进先出的队列了。

  • 每次 pop 的时候都拿翻转完了之后的栈
  • 如何 pop 没有数据了就继续从 push 里面翻转导入数据。

在这里插入图片描述

三、栈实现队列的代码实现

核心思路我们有了接下来就是如何实现了,插入和删除解决了。其他问题那就不是问题非常简单就解决了,下面我们来看看把!

3.1 栈实现队列的初始化

初始化和以前一样既然需要俩个栈来模拟实现队列,那么就需要俩个指针来管理栈区就够了:

  • 空间还是和以前 malloc 就好了。
  • 先创建队列的空间在 , malloc 的空间。

📚 代码演示:

typedef struct {ST pushst;ST popst;
} MyQueue;MyQueue* myQueueCreate() {MyQueue* new = (MyQueue*)malloc(sizeof(MyQueue));STInit(&new->pushst);STInit(&new->popst);return new;
}

3.2 栈实现队列判空

判空这就巨简单了,既然我们用了俩个栈来实现队列那么只要这俩个栈都为空不就行了。

  • 核心思想 STEmpty(&obj->pushst) && STEmpty(&obj->popst)
  • 判断栈区是否为空使用栈的判断就好了

📚 代码演示:

bool myQueueEmpty(MyQueue* obj) {return STEmpty(&obj->pushst) && STEmpty(&obj->popst);
}

3.3 栈实现队列的插入

插入这个就是最简单的了,直接往push栈里面插入就好了:

📚 代码演示:

void myQueuePush(MyQueue* obj, int x) {STPush(&obj->pushst,x);
}

3.4 栈实现队列删除

删除队列就是我们前面的思想:

  • 每次取pop 栈里面的元素
  • 如果 pop 为空的话那么就从 push栈里面 翻转导入就好了。

📚 代码演示:

int myQueuePop(MyQueue* obj) {if(STEmpty(&obj->popst)){while(STSize(&obj->pushst)){STPush(&obj->popst,STTop(&obj->pushst));STPop(&obj->pushst);}}int top = STTop(&obj->popst);   STPop(&obj->popst);return top;
}

3.5 栈实现队列的头元素

头元素的的访问就很简单了,我们 pop 栈的第一个栈顶元素就是头元素:

  • 去直接访问就好了。
  • 但是要注意 pop 为空的时候就需要导入一下了。

📚 代码演示:

int myQueuePeek(MyQueue* obj) {if(STEmpty(&obj->popst)){while(STSize(&obj->pushst)){STPush(&obj->popst,STTop(&obj->pushst));STPop(&obj->pushst);}}return STTop(&obj->popst);
}

3.6 栈实现队列的销毁

销毁还是和以前一样,把malloc的空间都销毁:

  • 然后再销毁队列本身的空间

📚 代码演示:

void myQueueFree(MyQueue* obj) {STDestroy(&obj->pushst);STDestroy(&obj->popst);free(obj);
}

四、栈实现队列的成果检验

好了以上就是栈实现队列的全过程了:

  • 对应练习题在这里: 用栈实现队列

📚 代码演示:

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>//#define N 10
//struct Stack
//{
//	int a[N];
//	int top;
//};typedef int STDataType;
typedef struct Stack
{STDataType* a;int top;int capacity;
}ST;void STInit(ST* ps);
void STDestroy(ST* ps);
void STPush(ST* ps, STDataType x);
void STPop(ST* ps);
STDataType STTop(ST* ps);int STSize(ST* ps);
bool STEmpty(ST* ps);void STInit(ST* ps)
{assert(ps);ps->a = NULL;ps->capacity = 0;ps->top = 0;
}void STDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->top = ps->capacity = 0;
}void STPush(ST* ps, STDataType x)
{assert(ps);// 11:40if (ps->top == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);if (tmp == NULL){perror("realloc fail");exit(-1);}ps->a = tmp;ps->capacity = newCapacity;}ps->a[ps->top] = x;ps->top++;
}void STPop(ST* ps)
{assert(ps);// assert(ps->top > 0);--ps->top;
}STDataType STTop(ST* ps)
{assert(ps);// assert(ps->top > 0);return ps->a[ps->top - 1];
}int STSize(ST* ps)
{assert(ps);return ps->top;
}bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}typedef struct {ST pushst;ST popst;
} MyQueue;MyQueue* myQueueCreate() {MyQueue* new = (MyQueue*)malloc(sizeof(MyQueue));STInit(&new->pushst);STInit(&new->popst);return new;
}void myQueuePush(MyQueue* obj, int x) {STPush(&obj->pushst,x);
}int myQueuePop(MyQueue* obj) {if(STEmpty(&obj->popst)){while(STSize(&obj->pushst)){STPush(&obj->popst,STTop(&obj->pushst));STPop(&obj->pushst);}}int top = STTop(&obj->popst);   STPop(&obj->popst);return top;
}int myQueuePeek(MyQueue* obj) {if(STEmpty(&obj->popst)){while(STSize(&obj->pushst)){STPush(&obj->popst,STTop(&obj->pushst));STPop(&obj->pushst);}}return STTop(&obj->popst);
}bool myQueueEmpty(MyQueue* obj) {return STEmpty(&obj->pushst) && STEmpty(&obj->popst);
}void myQueueFree(MyQueue* obj) {STDestroy(&obj->pushst);STDestroy(&obj->popst);free(obj);
}/*** Your MyQueue struct will be instantiated and called as such:* MyQueue* obj = myQueueCreate();* myQueuePush(obj, x);* int param_2 = myQueuePop(obj);* int param_3 = myQueuePeek(obj);* bool param_4 = myQueueEmpty(obj);* myQueueFree(obj);
*/

📝全篇总结

☁️ 好了以上就是栈的实现队列的全部解析了,总的来说只要掌握技巧就不难呢!核心思想掌握了那就直接秒杀.
看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注

💛 💙 💜 ❤️ 💚💓 💗 💕 💞 💘 💖
拜托拜托这个真的很重要!
你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。
在这里插入图片描述

这篇关于速学数据结构 | 我不允许还有人不会用栈实现队列!的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/358636

相关文章

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

Python实现字典转字符串的五种方法

《Python实现字典转字符串的五种方法》本文介绍了在Python中如何将字典数据结构转换为字符串格式的多种方法,首先可以通过内置的str()函数进行简单转换;其次利用ison.dumps()函数能够... 目录1、使用json模块的dumps方法:2、使用str方法:3、使用循环和字符串拼接:4、使用字符

Linux下利用select实现串口数据读取过程

《Linux下利用select实现串口数据读取过程》文章介绍Linux中使用select、poll或epoll实现串口数据读取,通过I/O多路复用机制在数据到达时触发读取,避免持续轮询,示例代码展示设... 目录示例代码(使用select实现)代码解释总结在 linux 系统里,我们可以借助 select、

Linux挂载linux/Windows共享目录实现方式

《Linux挂载linux/Windows共享目录实现方式》:本文主要介绍Linux挂载linux/Windows共享目录实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录文件共享协议linux环境作为服务端(NFS)在服务器端安装 NFS创建要共享的目录修改 NFS 配

通过React实现页面的无限滚动效果

《通过React实现页面的无限滚动效果》今天我们来聊聊无限滚动这个现代Web开发中不可或缺的技术,无论你是刷微博、逛知乎还是看脚本,无限滚动都已经渗透到我们日常的浏览体验中,那么,如何优雅地实现它呢?... 目录1. 早期的解决方案2. 交叉观察者:IntersectionObserver2.1 Inter

Spring Gateway动态路由实现方案

《SpringGateway动态路由实现方案》本文主要介绍了SpringGateway动态路由实现方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随... 目录前沿何为路由RouteDefinitionRouteLocator工作流程动态路由实现尾巴前沿S