[算法学习]两个栈实现一个队列

问题描述:

用两个栈实现一个队列,实现两个方法:入队appendTail,出队deleteHead

分析:

第一眼就能想到两个做法,

(1) 入队麻烦出队容易:

声明两个栈,一个是存数据用的栈(dataStack),一个是辅助用的栈(tempStack)。

入队操作时,先将dataStack中的所有元素出栈压入tempStack中,然后将要入队的元素压入tempStack中,再将tempStack所有元素出栈到dataStack,至此入队成功,dataStack栈顶元素就是第一个入队的元素(队头)。

出队操作时,只需将dataStack栈顶元素弹出返回就可以。

(2) 入队容易出队麻烦:

声明两个栈,一个是存数据用的栈(dataStack),一个是辅助用的栈(tempStack)。

入队操作时,只需要将入队元素压入dataStack就可以。

出队操作时,需要将dataStack全部元素出栈到tempStack中,tempStack弹出元素返回,然后再将tempStack剩下元素全部出栈到dataStack。


理一理代码思路

(1). 入队麻烦出队容易

  1. Stack<Integer> dataStack = new Stack<Integer>();
  2. Stack<Integer> tempStack = new Stack<Integer>();
  3. /**
  4. * 入队
  5. * @param item
  6. */
  7. public void appendTail(int item)
  8. {
  9. while (!dataStack.isEmpty())
  10. {
  11. tempStack.push(dataStack.pop());
  12. }
  13. tempStack.push(item);
  14. while (!tempStack.isEmpty())
  15. {
  16. dataStack.push(tempStack.pop());
  17. }
  18. }
  19. /**
  20. * 出队
  21. * @return
  22. * @throws Exception
  23. */
  24. public int deleteHead()
  25. {
  26. return dataStack.pop();
  27. }

(2). 入队容易出队麻烦

  1. Stack<Integer> dataStack = new Stack<Integer>();
  2. Stack<Integer> tempStack = new Stack<Integer>();
  3. /**
  4. * 入队
  5. * @param item
  6. */
  7. public void appendTail(int item)
  8. {
  9. dataStack.push(item);
  10. }
  11. /**
  12. * 出队
  13. * @return
  14. * @throws Exception
  15. */
  16. public int deleteHead() throws Exception
  17. {
  18. if(dataStack.isEmpty())
  19. {
  20. throw new Exception("队列为空!");
  21. }
  22. int head=0;
  23. while (!dataStack.isEmpty())
  24. {
  25. tempStack.push(dataStack.pop());
  26. }
  27. head=tempStack.pop();
  28. while (!tempStack.isEmpty())
  29. {
  30. dataStack.push(tempStack.pop());
  31. }
  32. return head;
  33. }

优化

思路:每次都要全部出栈全部出栈这样太麻烦,时间复杂度有点大。优化方案就是声明一个入队的栈(enStack)和一个出队的栈(deStack)。

入队时,将入队元素压入enStack中就可以。

出队时,做个判断,如果deStack为空,就将enStack的元素全部出栈压入deStack中,然后将deStack栈顶元素弹出返回即可。

这样,确实优化了。

  1. Stack<Integer> enStack=new Stack<Integer>(); // 用于入队的表
  2. Stack<Integer> deStack=new Stack<Integer>(); // 用于出队的表
  3. public void appendTail(int item)
  4. {
  5. enStack.push(item);
  6. }
  7. public int deleteHead()
  8. {
  9. if(deStack.isEmpty())
  10. {// 当出队的栈为空,那就从入队栈中获取元素更新。
  11. while(!enStack.isEmpty())
  12. {
  13. deStack.push(enStack.pop());
  14. }
  15. }
  16. // 如果deStack为空会抛一个EmptyStackException异常,这我就不处理了。
  17. return deStack.pop();
  18. }

来自为知笔记(Wiz)

时间: 2024-10-25 12:11:41

[算法学习]两个栈实现一个队列的相关文章

数据结构和算法之栈和队列一:两个栈模拟一个队列以及两个队列模拟一个栈

今天我们需要学习的是关于数据结构里面经常看到的两种结构,栈和队列.可以说我们是一直都在使用栈,比如说在前面递归所使用的的系统的栈,以及在链表倒序输出时介绍的自定义栈类Stack和使用系统的栈进行递归.那么,在这里我们就讲述一下这两个比较具有特色的或者说关系比较紧密的数据结构之间的互相实现问题. 一:两个栈模拟实现一个队列: 栈的特点是先进后出,然而队列的特点是先进先出. public class Queen(Stack s1,Stack s2){ //实现插入的方法 public void ad

每天一个小算法(6)---- 通过两个栈实现一个队列

这个算法也很简单,定义两个栈m_aStack.m_bStack,m_aStack负责push()数据,m_bStack负责front()数据. 思路:每一次front()取数据都会检查一下m_bStack是否为空,为空则把m_aStack的所有数据pop()出来push()到m_bStack中. 因为STL里有stack,直接拿来用了,代码使用C++,在linux/g++下编译运行成功: 1 #include <stack> 2 #include <stdio.h> 3 #incl

两个栈实现一个队列和两个队列实现一个栈【算法导论课后题】

关于两个栈实现一个队列和两个队列实现一个栈问题,网上有很多资料.这里只描述自己认为操作最少的方法. 两个栈实现一个队列 思想:假设两个栈分别为s1,s2.对s1进行入队,出队时,先判断s2是否为空,如果是则将s1中元素压入s2并弹出最上面元素,如果不是,则直接弹出s2最上面的元素. <span style="font-size:18px;">EnQueue(s1,s2,k){ push(s1,k)</span><span style="font-

使用两个栈实现一个队列

使用两个栈Stack1和Stack2来实现一个队列.其中一个栈作为主存放数据的,另外一个栈作为临时存放数据的栈.具体操作如下: enqueue: 栈Stack1的入栈操作. dequeue:将Stack1中的元素一个一个地全部依次出栈,并且在Stack1出栈的同时把出栈的元素作为参数对Stack2进行入栈操作.这步完成之后,执行Stack2出栈操作,这时就将原先在Stack1中最先入栈的元素弹出.最后再将Stack2中的元素一个一个地全部依次出栈,填到Stack1中. 实现代码如下: /** *

用两个栈实现一个队列

用两个栈实现一个队列的功能 解析: 假设两个栈A和B,且都为空. 可以认为栈A提供入队列的功能,栈B提供出队列的功能. 入队列:入栈A. 出队列: 如果栈B不为空,直接弹出栈B的数据. 如果栈B为空,则依次弹出栈A的数据,放入栈B中,再弹出栈B的数据. 代码如下: #include<iostream> #include<stack> using namespace std; template<class T> struct MyQueue { void push(T &

两个栈实现一个队列

问题描述: 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 解法分析: 首先题目要求用两个栈实现一个队列,那么就要先分析为什么这么做.队列的特点就像排队的"先到先得"一样,即先入队的就先出队:而栈则正好相反,特点是"后进先出",那么问题来了怎么用"后进先出"的得到"先进先出"? 传说中最简单通用但效率不高的方法(其实我还真没想到这么做)是,入队的时候用stack1来存储,当出队的时候,先把

web前端面试系列 - 数据结构(两个栈模拟一个队列)

一. 用两个栈模拟一个队列 思路一: 1. 一个栈s1作为数据存储,另一个栈s2,作为临时数据存储. 2. 入队时将数据压人s1 3. 出队时将s1弹出,并压人s2,然后弹出s2中的顶部数据,最后再将剩余数据弹出s2,并压人s1. 思路二: 1. 一个栈s1作为数据存储,另一个栈s2,作为临时数据存储. 2. 入队时,判断s1, 是否为空,如果不为空,则将数据直接压入s1, 如果为空,则将s2中的数据全部倒入s1,在将数据压人s1. 3. 出队时,判断s2, 是否为空,如果不为空,则直接弹出s2

两个栈实现一个队列,两个队列实现一个栈

1.两个栈实现一个队列 有三种思路: 思路一:将stack1作为存储空间,将stack2作为临时缓冲区,入队时,直接压入stac1,出队时,将stack1中的元素依次出栈压入stack2中,再将stack2的栈顶元素弹出,最后将stack2中的元素再倒回给stack1 思路二:入队时,判断stack1是否为空,如果stack1为空,则将stack2中的所有元素都倒入stack1中,再将元素直接压入stack1,否则,直接压入stack1中 出队时,判断stack2是否为空,如果stack2为空,

013使用两个栈实现一个队列(keep it up)

使用两个栈实现一个队列 队列是先进先出的数据结构(FIFO),栈是先进后出的数据结构(FILO), 用两个栈来实现队列的最简单方式是:进入队列则往第一个栈压栈, 出队列则将第一个栈的数据依次压入第二个栈,然后出栈. 两条规则: 1)进队列,则直接压入第一个栈 2)出队列,若果第二个栈不为空,直接pop(),如过第二个栈为空, 则把第一个栈中的数据全部压入第二个栈(第一个栈此时为空). 实际写代码时注意栈为空的情况. 代码: #include <iostream> #include <st