用栈实现队列

力扣题目链接(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. [转帖]Linux 防火墙开放特定端口 (iptables)

    查看状态: iptables -L -n 下面添加对特定端口开放的方法: 使用iptables开放如下端口 /sbin/iptables -I INPUT -p tcp --dport 8000 -j ...

  2. Nacos集群启动注意事项

    简介 Nacos是阿里巴巴开源的一套服务注册发现的应用 使用简单灵活, 是spring Cloud Alibaba的组成部分 现在拆分微服务的部署情况下,极大的需求nacos服务作为支撑 单点情况下存 ...

  3. 一个简单的监控java进程获取日志的办法

    公司里面一个长时间运行的环境会出现问题, 这边简单写了一个脚本自动获取日志信息 脚本如下 注意 我的path 其实就是复用的 我们应用里面的jdk  剩下的就非常简单了. 每个日志都自动打包 并且移除 ...

  4. 你不知道的Linux shell操作

    Linux Shell 脚本入门教程 Linux Shell 脚本是一种强大的工具,它允许您自动化日常任务和复杂操作.在本教程中,我们将逐步介绍几个实用的 Shell 脚本示例.每个示例都将详细说明, ...

  5. overflow的所有值,overlay不占位

    visible: 默认值.内容不会被修剪,会呈现在元素框之外. hidden: 内容会被修剪,并且其余内容是不可见的. scroll: 内容会被修剪,总是显示滚动条. auto: 内容被修剪,超出浏览 ...

  6. 同步存储读取vuex中store中的值

    main.js import store from "./store"; Vue.prototype.$store = store; 在 store中的index.js中 impo ...

  7. TienChin-系统功能介绍

    线索管理 添加线索 查看线索 删除线索 修改线索 分配线索: ​将录入到系统的线索,分配给某一个市场专员去处理 跟进线索: ​持续跟进一条线索 1.判断是否伪线索 2.持续跟进,每次跟进需要有记录 3 ...

  8. paddleNLP-BUG和一些细节记录【一】

    1.TypeError: isfile() takes 1 positional argument but 2 were given File "/root/miniconda3/envs/ ...

  9. Gin 响应方式

    响应 1. 字符串方式 r.GET("/user/save", func(ctx *gin.Context) { ctx.String(http.StatusOK, "t ...

  10. 解决线程不安全的方式(Java)

    一.同步代码块 package com.synchronized1; // 买票示例 // 使用同步代码块解决线程安全问题 public class TicketRunnableImp impleme ...