用栈实现队列

力扣题目链接(opens new window)

使用栈实现队列的下列操作:

push(x) -- 将一个元素放入队列的尾部。

pop() -- 从队列首部移除元素。

peek() -- 返回队列首部的元素。

empty() -- 返回队列是否为空。

示例:

MyQueue queue = new MyQueue();
queue.push(1);
queue.push(2);
queue.peek(); // 返回 1
queue.pop(); // 返回 1
queue.empty(); // 返回 false

说明:

  • 你只能使用标准的栈操作 -- 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
  • 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
  • 假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)

栈的基本操作

示例:

#include <stack>

//栈容器常用接口
void test01()
{
//创建栈容器 栈容器必须符合先进后出
stack<int> s; //向栈中添加元素,叫做 压栈 入栈
s.push(10);
s.push(20);
s.push(30); while (!s.empty()) {
//输出栈顶元素
cout << "栈顶元素为: " << s.top() << endl;
//弹出栈顶元素
s.pop();
}
cout << "栈的大小为:" << s.size() << endl; } int main() { test01(); system("pause"); return 0;
}

总结:

  • 入栈 --- push
  • 出栈 --- pop
  • 返回栈顶 --- top
  • 判断栈是否为空 --- empty
  • 返回栈大小 --- size

思路

题意是要模拟一个队列的行为,用栈

队列是什么?前后都打开的一种结构,也就是说可以实现先进先出

这点用一个栈不太好还原,所以要模拟先进先出至少得使用两个 stack ,

分别为进栈(stack_in)和出栈(stack_out)

当模拟队列 push 时,我们同样只需要将数据 push 进 stack_in 即可,该动作可以直接调用官方为stack提供的 push 函数

当模拟队列 pop 时,我们要先将 stack_in 的所有数据 pop 出来再 push 进 stack_out 。

此时,之前先进入 stack_in 的数据就在 stack_out 的 top 位置了,剩下的我们只需要对 stack_out 进行 pop 操作即可模拟队列的pop。

对应的模拟动画如下:

注意:在将 stack_in 的数据放入 stack_out 之前,必须先检查 stack_out 是否为空,不为空就直接从stack_out 往外弹数据。且往放 stack_out 数据时必须一次性全部放完,不然上述两种情况都会导致数据的顺序出错。

代码

步骤:(实现pop)

1、判断出栈是否为空

2、循环将入栈数据压入出栈

3、然后从stack_out的栈顶获取数据

class MyQueue {
public:
//定义两个栈
stack<int>stack_in;
stack<int>stack_out; MyQueue() { } void push(int x) {
stack_in.push(x);
} int pop() {
int tmp;
//判断stack_out是否为空,不为空就往里面不断push数据
if(stack_out.empty()){
//将stack_in的全部数据push入
while(!stack_in.empty()){
// stack_out.push(stack_in.pop()) //错误,应该让stack_out先获取stack_in的栈顶数据,然后再pop走
// stack_out.push(stack_in.top());//虽然在本题不会报错,但
// stack_in.pop();//这种写法会在别的同类型的题中出错,所以统一使用下面的写法
tmp = stack_in.top();
stack_in.pop();
stack_out.push(tmp);
}
}
//然后从stack_out获取数据
int res = stack_out.top();
stack_out.pop();
return res; } int peek() {//即查看栈顶数据
int res = this->pop();//直接复用类内的pop
//然后记得再把数据push回来
stack_out.push(res);
return res; } bool empty() {
return stack_in.empty() && stack_out.empty();
}
};
注意点

1、对栈进行pop操作是没有返回值的,也就是说pop之后,栈顶的数据就没了,要读数据用top读

2、能复用就复用,优雅且专业

用队列实现栈

力扣题目链接(opens new window)

使用队列实现栈的下列操作:

  • push(x) -- 元素 x 入栈
  • pop() -- 移除栈顶元素
  • top() -- 获取栈顶元素
  • empty() -- 返回栈是否为空

注意:

  • 你只能使用队列的基本操作-- 也就是 push to back, peek/pop from front, size, 和 is empty 这些操作是合法的。
  • 你所使用的语言也许不支持队列。 你可以使用 list 或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
  • 你可以假设所有操作都是有效的(例如, 对一个空的栈不会调用 pop 或者 top 操作)

queue基本操作

示例:

#include <queue>
#include <string>
class Person
{
public:
Person(string name, int age)
{
this->m_Name = name;
this->m_Age = age;
} string m_Name;
int m_Age;
}; void test01() { //创建队列
queue<Person> q; //准备数据
Person p1("唐僧", 30);
Person p2("孙悟空", 1000);
Person p3("猪八戒", 900);
Person p4("沙僧", 800); //向队列中添加元素 入队操作
q.push(p1);
q.push(p2);
q.push(p3);
q.push(p4); //队列不提供迭代器,更不支持随机访问
while (!q.empty()) {
//输出队头元素
cout << "队头元素-- 姓名: " << q.front().m_Name
<< " 年龄: "<< q.front().m_Age << endl; cout << "队尾元素-- 姓名: " << q.back().m_Name
<< " 年龄: " << q.back().m_Age << endl; cout << endl;
//弹出队头元素
q.pop();
} cout << "队列大小为:" << q.size() << endl;
} int main() { test01(); system("pause"); return 0;
}

总结:

  • 入队 --- push
  • 出队 --- pop
  • 返回队头元素 --- front
  • 返回队尾元素 --- back
  • 判断队是否为空 --- empty
  • 返回队列大小 --- size

思路

用一个队列就可以模拟栈的行为

一个队列在模拟栈弹出元素的时候只要将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部,此时再去弹出元素就是栈的顺序了。

代码

步骤:(实现pop)

1、获取队列长度qLen

2、循环,只需循环qLen-1的部分,最后一个元素不用动。不断获取队头数据再加入队尾,然后pop调当前数据

3、循环结束后,现在队中元素的顺序就颠倒了(与栈顺序一致),接下来就从队头拿数据就行,

class MyStack {
public:
//创建队列
queue<int> q; MyStack() { } void push(int x) {
q.push(x);
} int pop() {
//获取队列长度
int qLen = q.size();
//需要循环的部分不包含最后一个数
qLen--;
while(qLen--){
//将队头的数据push到队尾
q.push(q.front());
//弹出当前队头数据
q.pop();
}
//已获得需要的数据顺序
//一个一个获取即可
int res = q.front();
q.pop();
return res;
} int top() {
//在栈里面的第一个元素,其实就是队列的最后一个元素,用back方法可以获取到
return q.back();
} bool empty() {
return q.empty();
}
};

TBD

【LeetCode栈与队列#01】队列的基本操作:用栈模拟队列和用队列模拟栈的更多相关文章

  1. 使用LinkedList模拟一个堆栈或者队列数据结构

    使用LinkedList模拟一个堆栈或者队列数据结构. 堆栈:先进后出  如同一个杯子. 队列:先进先出  如同一个水管. import java.util.LinkedList; public cl ...

  2. C# 模拟一个处理消息队列的线程类 Message Queue

    // 模拟一个处理消息队列的类 class MessageHandler { // 消息队列 private Queue<string> messageQue = new Queue< ...

  3. java集合 collection-list-LinkedList 模拟一个堆栈或者队列数据结构。

    /* 使用LinkedList模拟一个堆栈或者队列数据结构. 堆栈:先进后出 如同一个杯子. 队列:先进先出 First in First out FIFO 如同一个水管. */ import jav ...

  4. Java LinkedList特有方法程序小解 && 使用LinkedList 模拟一个堆栈或者队列数据结构。

    package Collection; import java.util.LinkedList; /* LinkedList:特有的方法 addFirst()/addLast(); getFirst( ...

  5. 面试题:使用LinkedList来模拟一个堆栈或者队列数据结构

    请使用LinkedList来模拟一个堆栈或者队列数据结构. 堆栈:先进后出 First In Last Out  (FILO) 队列:先进先出 First In First Out  (FIFO) 我 ...

  6. java 使用LinkedList模拟一个堆栈或者队列数据结构

    近期在复习下java基础,看了下java基础,在看到集合时突然发现想起来曾经面试有一道笔试题:模拟一个堆栈或者队列数据结构,当时还没做出来,今天就写一下,首先得明确堆栈和队列的数据结构 堆栈:先进后出 ...

  7. C语言数据结构-链式队列的实现-初始化、销毁、清空、长度、队列头元素、插入、删除、显示操作

    1.数据结构-链式队列的实现-C语言 typedef struct QNode { int data; struct QNode *next; }QNode,*QueuePtr; typedef st ...

  8. LeetCode初级算法--数组01:只出现一次的数字

    LeetCode初级算法--数组01:只出现一次的数字 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn. ...

  9. LeetCode初级算法--字符串01:反转字符串

    LeetCode初级算法--字符串01:反转字符串 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.ne ...

  10. LeetCode初级算法--链表01:反转链表

    LeetCode初级算法--链表01:反转链表 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/ ...

随机推荐

  1. [转帖]Nacos的版本支持情况

    https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E 由于 Spring ...

  2. [转帖]并发控制- sched_yield 函数

    函数说明 函数原型 #include <sched.h> int sched_yield(void); 1 2 sched_yield的作用是让出处理器,调用时会导致当前线程放弃CPU,进 ...

  3. Linux上面Shell简单进行数值计算的办法

    1. 自己简单写了一个脚本 来计算 一个服务进程启动的耗时, 精度要求不高 10秒上下就可以. 在程序执行之前和之后的处理 在最前面设置一句time1=`date +%s`在末尾一句设置time2=` ...

  4. canvas操作图片像素点保证你看的明明白白

    开场白 今天遇到一个场景:就是更改一个图片的颜色: 当听到这个.我直呼好家伙:这个是要上天了呀. 但是仔细一思考:借助canvas好像也能实现: 于是下来研究了一下,并不难: 我们下面来看看怎么实现的 ...

  5. Qt中qreal的坑

    今天在写Qt的时候遇到了一个bug:同样一个方程在PC机上算的结果是11,但在arm-Linux设备上算出来的结果是12,我自己用计算器按出来的结果也是12. 该段程序是这样的: maxnumbar ...

  6. go多版本管理

    在日常开发工作过程中,很多时候我们都需要在自己的机器上安装多个go版本,像是go1.16引入的embed,go1.18引入了泛型:又或是自己本地使用的是最新版,但公司的项目中使用的go1.14.go1 ...

  7. OpenIM集群(非k8s)部署文档

    自行部署etcd/zookeeper/mysql/kafka/mongo/redis集群,可以根据此性能评估服务器需求. 以下是针对一台华为云主机s3的压测数据:8核16G内存,普通磁盘(非SSD)( ...

  8. 策略模式学习,使用go实现策略模式

    策略模式 定义 优点 缺点 使用场景 代码实现 策略模式和工厂模式的区别 参考 策略模式 定义 策略模式定义了算法家族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化,不会影响到客户端的使用 ...

  9. Leetcode刷题第二天-贪心

    655:非递减数列 链接:665. 非递减数列 - 力扣(LeetCode) 直接找最大最小值进行替换不行,[1,5,4,6,7,8,9]最大最小值所处位置可能是非递减数列 如果nums[i]> ...

  10. MySQL中 int(11)和int(10)有没有区别!!

    结论:int(11)  int(3)  int(20)  若不勾选填充0,那么效果统统一样,若勾选了填充0:查询出来的效果 会是这样: int(11)  00000000123 int(3)  123 ...