1. 什么是栈 队列

  2. 如何仅用两个栈模拟实现队列

  3. 如何仅用两个队列模拟实现栈

  4. 循环队列

什么是栈 队列

栈 本质是一种线性表 ,秉持着 “后进先出”原则; 想象不出来的朋友可以类比 “弹匣”

队列 也是一种线性数据结构 它只允许一端进数据(队尾),另一端出数据(队头);

如何仅用两个栈模拟实现队列

在模拟实现过程中 对实现队列的 出列 是最麻烦的

我们将两个栈取名 分别是 pushstack popstack;

入列我们直接压栈pushstack即可 push 1 2 3 4

我们要pop出 1  ;而队列是 先进先出 栈是 后进先出;出列如何实现呢

我们可以用倒数据的方法

如图 即是popstack接收 再依次pop掉 非常方便

下面来看具体的代码实现

typedef struct {//入队栈Stack pushST;//出队栈Stack popST;
} MyQueue;/** Initialize your data structure here. */
MyQueue* myQueueCreate(int maxSize) {MyQueue* pqueue = (MyQueue*)malloc(sizeof(MyQueue));StackInit(&pqueue->pushST, maxSize);StackInit(&pqueue->popST, maxSize);return pqueue;
}/** Push element x to the back of queue. */
void myQueuePush(MyQueue* obj, int x) {//入队栈进行入栈操作StackPush(&obj->pushST, x);
}/** Removes the element from in front of queue and returns that element. */
int myQueuePop(MyQueue* obj) {//如果出队栈为空,导入入队栈的元素if(StackEmpty(&obj->popST) == 0){while(StackEmpty(&obj->pushST) != 0){StackPush(&obj->popST, StackTop(&obj->pushST));StackPop(&obj->pushST);}}int front = StackTop(&obj->popST);//出队栈进行出队操作StackPop(&obj->popST);return front;
}/** Get the front element. */
int myQueuePeek(MyQueue* obj) {//类似于出队操作if(StackEmpty(&obj->popST) == 0){while(StackEmpty(&obj->pushST) != 0){StackPush(&obj->popST, StackTop(&obj->pushST));StackPop(&obj->pushST);}}return StackTop(&obj->popST);
}/** Returns whether the queue is empty. */
bool myQueueEmpty(MyQueue* obj) {return StackEmpty(&obj->pushST) == 0&&  StackEmpty(&obj->popST) == 0;
}void myQueueFree(MyQueue* obj) {StackDestroy(&obj->pushST);StackDestroy(&obj->popST);free(obj);
}

如何仅用两个队列模拟实现栈

用队列模拟实现栈 做法和上题类似 还是“倒数据” 但在具体实现中略有不同 会麻烦一些

push 到一个非空队列中即可 (两个都是空 任意即可)

pop功能 需要倒数据

将非空队列中的数据 依次插入到空队列中 只剩下需要pop掉的数据 再pop掉即可

此时 非空队列变成空队列 空队列变成非空队列了

后续要实现 push 和pop 即循环这几个步骤就行

下面我们来看下具体的代码实现

typedef struct {Queue q1;Queue q2;} MyStack;/** Initialize your data structure here. */
MyStack* myStackCreate(int maxSize) {MyStack* pst = (MyStack*)malloc(sizeof(MyStack));QueueInit(&pst->q1);QueueInit(&pst->q2);return pst;
}/** Push element x onto stack. */
void myStackPush(MyStack* obj, int x) {//给非空队列进行入队操作if(QueueEmpty(&obj->q1) != 0){QueuePush(&obj->q1, x);}else{QueuePush(&obj->q2, x);}
}/** Removes the element on top of the stack and returns that element. */
int myStackPop(MyStack* obj) {//把非空队列的除最后一个元素之外的剩余元素全部入队空队列Queue* pEmpty = &obj->q1, *pNonEmpty = &obj->q2;if(QueueEmpty(&obj->q1) != 0){pEmpty = &obj->q2;pNonEmpty = &obj->q1;}while(QueueSize(pNonEmpty) > 1){QueuePush(pEmpty, QueueFront(pNonEmpty));QueuePop(pNonEmpty);}int top = QueueFront(pNonEmpty);//队尾元素出队QueuePop(pNonEmpty);return top;
}/** Get the top element. */
int myStackTop(MyStack* obj) {//获取非空队列的队尾元素Queue* pEmpty = &obj->q1, *pNonEmpty = &obj->q2;if(QueueEmpty(&obj->q1) != 0){pEmpty = &obj->q2;pNonEmpty = &obj->q1;}return QueueBack(pNonEmpty);
}/** Returns whether the stack is empty. */
bool myStackEmpty(MyStack* obj) {return !(QueueEmpty(&obj->q1) | QueueEmpty(&obj->q2));
}void myStackFree(MyStack* obj) {QueueDestory(&obj->q1);QueueDestory(&obj->q2);free(obj);
}

看到这里 我们已经学会了如何仅用两个栈来实现队列 和 如何仅用两个队列来实现栈

接下来 我们来学习一个 循环队列

循环队列 (惊喜  不看阳后悔)

什么是循环队列

一种队列 固定大小 首尾相连 可以利用队列之前用过的空间;一旦队列满了 我们就不能插入下一个元素

那我们应该用什么来实现循环队列呢 数组? 链表?

相信很多人第一眼就 觉得链表紫腚行  确实 但那是双向循环链表 而单链表行不行呢?

我们来分析下

1.如何判断空状态 和 满状态?

在这里我们使用 “添加一个空余节点”的方法,这样的话

可以 用front == rear 来判空

(rear + 1)%(k+1)== front 来判满

2.如何取队尾数据?

总结:单链表要实现这个就十分麻烦 所以我们使用数组

下面来看看代码实现

/*
解题思路:
通过一个定长数组实现循环队列
入队:首先要判断队列是否已满,再进行入队的操作,入队操作需要考虑索引循环的问题,当索引越界,需要让它变成最小值
出队:首先要判断队列是否为空,再进行出队操作,出队也需要考虑索引循环的问题
判空: 队头 == 队尾
判满: 队尾 + 1 == 队头
*/
typedef struct {int* queue;int front;int rear;int k
} MyCircularQueue;/** Initialize your data structure here. Set the size of the queue to be k. */
//创建一个可以存放k个元素的循环队列,实际申请的空间为k + 1
MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* pcq = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));pcq->queue = (int*)malloc(sizeof(int)*(k+1));pcq->front = 0;pcq->rear = 0;pcq->k = k;return pcq;
}/** Insert an element into the circular queue. Return true if the operation is successful. */
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {//判满if((obj->rear+1)%(obj->k+1) == obj->front){return false;}//队尾入队obj->queue[obj->rear++] = value;//如果队尾越界,更新为最小值if(obj->rear == obj->k+1)obj->rear = 0;return true;
}/** Delete an element from the circular queue. Return true if the operation is successful. */
bool myCircularQueueDeQueue(MyCircularQueue* obj) {//判空if(obj->front == obj->rear)return false;//队头出队++obj->front;//如果队头越界,更新为最小值if(obj->front == obj->k+1)obj->front = 0;return true;
}/** Get the front item from the queue. */
int myCircularQueueFront(MyCircularQueue* obj) {if(obj->front == obj->rear)return -1;elsereturn obj->queue[obj->front];
}/** Get the last item from the queue. */
int myCircularQueueRear(MyCircularQueue* obj) {if(obj->front == obj->rear)return -1;//队尾元素再rear索引的前一个位置,如果rear为0,//则队尾元素在数组的最后一个位置if(obj->rear == 0)return obj->queue[obj->k];elsereturn obj->queue[obj->rear-1];
}/** Checks whether the circular queue is empty or not. */
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {return obj->front == obj->rear;
}/** Checks whether the circular queue is full or not. */
bool myCircularQueueIsFull(MyCircularQueue* obj) {return (obj->rear+1)%(obj->k+1) == obj->front;
}void myCircularQueueFree(MyCircularQueue* obj) {free(obj->queue);free(obj);
}

循环队列学会了吗 还不快点一键三连 拜托拜托啦!!!

一文搞定栈和队列的相互实现(内置惊喜)相关推荐

  1. 一文搞定数据结构(图解)

    搞定顺序表: https://blog.csdn.net/qq_44443986/article/details/111387150 搞定链表: https://blog.csdn.net/qq_44 ...

  2. 一文搞定 Spring Data Redis 详解及实战

    转载自  一文搞定 Spring Data Redis 详解及实战 SDR - Spring Data Redis的简称. Spring Data Redis提供了从Spring应用程序轻松配置和访问 ...

  3. 一文搞定面试中的二叉树问题

    一文搞定面试中的二叉树问题 版权所有,转载请注明出处,谢谢! http://blog.csdn.net/walkinginthewind/article/details/7518888 树是一种比较重 ...

  4. php带参数单元测试_一文搞定单元测试核心概念

    基础概念 单元测试(unittesting),是指对软件中的最小可测试单元进行检查和验证,这里的最小可测试单元通常是指函数或者类.单元测试是即所谓的白盒测试,一般由开发人员负责测试,因为开发人员知道被 ...

  5. 【Python基础】一文搞定pandas的数据合并

    作者:来源于读者投稿 出品:Python数据之道 一文搞定pandas的数据合并 在实际处理数据业务需求中,我们经常会遇到这样的需求:将多个表连接起来再进行数据的处理和分析,类似SQL中的连接查询功能 ...

  6. 一文搞定Swing和Qt按钮和文本框的创建

    一文搞定Swing和Qt按钮和文本框的创建 Qt的截图 java的 源码 package com.lujun;import java.awt.Container;import javax.swing. ...

  7. 一文搞定C#关于NPOI类库的使用读写Excel以及io流文件的写出

    一文搞定C#关于NPOI类库的使用读写Excel以及io流文件的写出 今天我们使用NPOI类库读写xlsx文件, 最终实现的效果如图所示 从太平洋官网下载相应的类库,大概4~5MB,不要从github ...

  8. 一文搞定Qt读写excel以及qt读写xml数据

    一文搞定Qt读写excel以及qt读写xml数据 最终的实现效果图 RC_ICONS = logo.ico .pro文件同级目录下加入 logo.ico 图标文件,运行文件,文件的图标就被写入软件 u ...

  9. 【全网最全】一文搞定 Linux 压缩、解压哪些事儿

    一文搞定 Linux 压缩.解压哪些事儿 Linux 常用的解压和压缩命令如下: 1..tar # 解包 tar xvf FileName.tar # 打包 tar cvf FileName.tar ...

最新文章

  1. python处理声音
  2. 成员函数的const究竟修饰的是谁
  3. Wireshark使用学习
  4. Python基础知识(第四天)
  5. caffe学习(六):使用python调用训练好的模型来分类(Ubuntu)
  6. 6-3 逆序数据建立链表
  7. 【白话科普】10s 从零看懂 H5
  8. java抓取图片_java 抓取网页的图片
  9. js_!和!!的使用
  10. Java笔记-Log4j在Spring Boot中的使用
  11. bs模式Java web,基于BS模式的即时通讯系统的设计与实现(MyEclipse)
  12. Axure 经典实例高保真原型下载(Axure高保真酒店管理交互组件连锁酒店erp酒店企业web端后台管理财务管理会员管理网销管理报表管理))
  13. 用python快速将excel(含多sheet)导入MySQL(兼容中文)
  14. python控制窗口_Python : Turtle窗口控制
  15. mac上安装搭建Appium环境
  16. myeclipse 创建和访问 servlet 项目
  17. Windows系统镜像下载
  18. PhpStorm Unhandled exceptions错误解决
  19. Linux笔记之Docker安装,基于Debian 11(bullseye)
  20. apmserv 5.2.6 升级php,Windows + APMServ5.2.6/PHP5以上

热门文章

  1. UITextField shouldChangeCharactersInRange获取实时数据并执行联想搜索和搜索
  2. ETL常用的三种工具介绍及对比Datastage,Informatica
  3. vue 使用quill富文本编辑 增加表格功能
  4. 我的网站被攻击了,运维大佬给了我自动封禁ip的脚本。
  5. C语言实现PTA6-3 求集合数据的均方差
  6. 百度云服务器win系统,windows10系统下百度云无法打开如何解决
  7. bp神经网络的应用领域,BP神经网络能够做什么
  8. 72家品牌上榜,联诚发“LCF”获评第十九届深圳知名品牌!
  9. android vold文件夹,android vold
  10. 天梯赛刷题1:Prime Path