用栈实现队列

力扣题目链接(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. [转帖]Elasticsearch-sql 用SQL查询Elasticsearch

    https://www.cnblogs.com/kangoroo/p/7273493.html https://www.cnblogs.com/kangoroo/p/7273493.html Elas ...

  2. [译]深入了解现代web浏览器(三)

    本文是根据Mariko Kosaka在谷歌开发者网站上的系列文章https://developer.chrome.com/blog/inside-browser-part3/ 翻译而来,共有四篇,该篇 ...

  3. 【JS 逆向百例】层层嵌套!某加速商城 RSA 加密

    声明 本文章中所有内容仅供学习交流,敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 逆向目标 目标:某加速商城登录接口 ...

  4. # 继续前行github star突破8k即时通讯IM开源项目OpenIM版本发布计划

    项目简介 OpenIM继续领跑开源IM领域,在广大开发者的支持下,目前github star突破8k.在数据泄露.信息外泄.隐私滥用的时代,IM私有化部署需求旺盛.其中,政企协同办公对IM需求猛增,随 ...

  5. IDM(最佳的Windows下载工具)

    如果你是一名互联网"老司机",那么一定听过「IDM」这款下载工具的大名!它的全名叫做 Internet Download Manager (互联网下载管理器),缩写就是 IDM. ...

  6. 手把手教学构建证券知识图谱/知识库(含码源):网页获取信息、设计图谱、Cypher查询、Neo4j关系可视化展示

    手把手教学构建证券知识图谱/知识库(含码源):网页获取信息.设计图谱.Cypher查询.Neo4j关系可视化展示 demo展示: 代码结构 stock-knowledge-graph/ ├── __i ...

  7. C/C++ 进程线程操作技术

    手动创建单进程: 下面通过一个实例来分别演示进程的创建函数. #include <windows.h> #include <stdio.h> BOOL WinExec(char ...

  8. Linux 配置Quota磁盘配额

    由于Linux是一个多用户管理的操作系统,而Linux默认情况下并不限制每个用户使用磁盘空间的大小,假如某个用户疏忽或者恶意占满磁盘空间,将导致系统磁盘无法写入甚至崩溃,为了保证系统磁盘的有足够的剩余 ...

  9. C/C++ 动态与静态内存补丁

    现动态内存补丁(读取): 这种补丁是把程序加载到内存中以后对其进行修改,常用于加壳程序的破解. #include <stdio.h> #include <Windows.h> ...

  10. 分享四个实用的vue自定义指令

    v-drag 需求:鼠标拖动元素 思路: 元素偏移量 = 鼠标滑动后的坐标 - 鼠标初始点击元素时的坐标 + 初始点击时元素距离可视区域的top.left 将可视区域作为边界,限制在可视区域里面拖拽 ...