美文网首页
由两个栈实现一个队列

由两个栈实现一个队列

作者: Sophia_dd35 | 来源:发表于2018-07-26 16:53 被阅读26次

对于一个栈来说遵循 pop 操作时从栈的顶部取一个元素,对于队列来说 poll 操作时从队列队首取一个元素。所以该题翻译过来就是使用两个栈定义一种先放入的元素,最先被取出的数据结构。

此题应考虑到两种情况,首先最简单的一种情况,假设有 1,2,3,4,5 个元素依次进入自定义的队列,再依次取出。由于是进栈操作都进行完了才进行出栈操作,所以我们只需在元素出队时,将进栈元素倒入另一个空栈中即可。示意图如下:



再一种情况是,如果 add poll 操作是交替进行的,那么如何保证数据结构先进先出的定义呢?比如先放入 1,2,3然后要进行一次取出操作取出 1,随后在进行 add 操作放入4,5,这种情况下如何操作两个栈,才能保证之后再取出的时候元素为 2,3,4,5 顺序?实际上我们只需要保证以下两点就可以:

  • 如果 StackA(最开始add元素的那个栈) 要往 StackB 中压入元素,那么必须选择一次性全部压入。
  • 无论什么时候从队列中取元素,必须保证元素是从 StackB 中 pop 出的,也就是说,当 StackB 不为空的时候绝不能再次向 StackB 中压入元素

为了方便理解可以看下边这幅图:


明白了需要注意的点后就是该写代码的时候了,需要注意的点在图中已经用红色字体标出了,也就是在存入元素一直往 StackA 中存,取元素是从 StackB 中取,但要注意的是取的时候需要保证 StackB 为空的时候要先将 StackA 中元素一次性压如 StackB 中,在进行从 StackB 中取的操作。

    public static class  TwoStackQueue<E>{
        private Stack<E> stackA;
        private Stack<E> stackB;

        public TwoStackQueue() {
            stackA = new Stack<>();
            stackB = new Stack<>();
        }

        /**
         * 添加元素逻辑
         * @param e 要添加的元素
         * @return 这里只是遵循 Queue 的习惯,这里简单处理返回 true 即可
         */
        public boolean add(E e){
            stackA.push(e);
            return true;
        }

        /**
         * 去除元素的时候需要判断两个地方,StackA & StackB 是否都为空
         * StackB 为空的时候将StackA中的元素全部依次压入 StackB
         * @return 返回队列中的元素 如果队列为空返回 null
         */
        public E poll(){
            //如果队列中没有元素则直接返回空,也可以选择抛出异常
            if (stackB.isEmpty() && stackA.isEmpty()){
                return null;
            }
            
            if (stackB.isEmpty()){
                while (!stackA.isEmpty()){
                    stackB.add(stackA.pop());
                }
            }
            
            return stackB.pop();
        }

        /**
         * peek 操作不取出元素,只返回队列头部的元素值 
         * @return 队列头部的元素值
         */
        public E peek(){
            //如果队列中没有元素则直接返回空,也可以选择抛出异常
            if (stackB.isEmpty() && stackA.isEmpty()){
                return null;
            }

            if (stackB.isEmpty()){
                while (!stackA.isEmpty()){
                    stackB.add(stackA.pop());
                }
            }

            return stackB.peek();
        }
    }

相关文章

  • 队列、栈

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

  • 栈和队列

    两个栈实现队列 两个队列实现栈

  • 栈和队列的相互实现

    两个栈实现队列: 一个栈用来入,一个栈用来出 两个队列实现栈: 入栈的时候正常存入一个队列,出栈的时候用另一个队列...

  • 栈&队列

    一、栈&队列总结 栈/队列的应用接雨水验证栈序列滑动窗口的最大值 栈/队列的特殊实现用两个栈实现队列用两个队列实现...

  • LeetCode 每日一题 [43] 用两个栈实现队列

    LeetCode 用两个栈实现队列 [简单] 用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appen...

  • 剑指Offer

    09 用两个栈实现队列 用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 del...

  • 剑指Offer(五)

    剑指Offer(五) 用两个栈实现队列 题目描述: 用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列...

  • LeetCode题解之用两个栈实现队列

    用两个栈实现队列 题目描述 用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 d...

  • 面试题09. 用两个栈实现队列

    用两个栈实现队列 题目描述 用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 d...

  • 剑指offer之栈队列堆

    [TOC] 9. 用两个栈实现队列 用两个栈来实现一个队列,完成队列的 Push 和 Pop 操作。 mysolu...

网友评论

      本文标题:由两个栈实现一个队列

      本文链接:https://www.haomeiwen.com/subject/enibmftx.html