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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[算法学习]两个栈实现一个队列相关的知识,希望对你有一定的参考价值。

问题描述:
用两个栈实现一个队列,实现两个方法:入队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. }




以上是关于[算法学习]两个栈实现一个队列的主要内容,如果未能解决你的问题,请参考以下文章

用两个栈实现队列

日常算法练习题用两个栈实现队列(每天进步一点点系列)

Python数据结构与算法(3.4)——队列相关应用与习题

javajava两个栈实现一个队列&两个队列实现一个栈

算法:用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。《剑指offer》

算法_栈实现队列篇