由两个栈组成的队列-日常算法rank

题目:编写一个类,用两个栈实现队列,支持队列的基本操作,add,poll,peek。

实现思路:

实现思路,队列是先进先出,栈是先进先出,如果栈能将出栈逆反过来就是队列了。所以,一个栈stackPush作为入队存储,一个栈StackPop作为出队,就可以做到先进先出了。但是里面出队需要一个保证:poll或者peek,当stackPop是空的时候,需要先将入栈所有元素都倒入stackPop里。这步骤必须保证,倾倒所有已入栈的元素。比如正在哗哗啦啦的写入入栈,1,2,3,4这个时候,要出栈,而且stackPop是空的,这个时候必须先锁住入栈这个对象,禁止往里面写,先将里面的1,2,3,4倒入出栈对象里。否则,你现在出栈,4到stackPop,然后因为没有锁住,现在stackPush入栈了5,再倾倒就是5,4.后来没有写入的了,出栈stackPop存放,从栈顶倒底部就是,1,2,3,5,4就错了。

看代码详解:

public class TwoStackQueue {
    //实现思路,队列是先进先出,栈是先进先出,如果栈能将出栈逆反过来就是队列了。
    //所以,一个栈stackPush作为入队存储,一个栈StackPop作为出队,就可以做到先进先出了
    //但是里面出队需要一个保证:poll或者peek,当stackPop是空的时候,需要先将入栈所有元素都倒入stackPop里。
    //这步骤必须保证,倾倒所有已入栈的元素。比如正在哗哗啦啦的写入入栈,1,2,3,4这个时候,要出栈,
    //而且stackPop是空的,这个时候必须先锁住入栈这个对象,禁止往里面写,先将里面的1,2,3,4倒入出栈对象里。
    //否则,你现在出栈,4到stackPop,然后因为没有锁住,现在stackPush入栈了5,再倾倒就是5,4.后来没有写入的了,
    //出栈stackPop存放,从栈顶倒底部就是,1,2,3,5,4就错了。
    public Stack stackPush;
    public Stack stackPop;

    public TwoStackQueue() {
        stackPop = new Stack();
        stackPush = new Stack();
    }

    //队列添加元素
    public void add(int n) {
        stackPush.push(n);
    }

    //队列出队
    public int pop() {
        if (stackPop.isEmpty() && stackPush.isEmpty()) {//如果队列为空
            throw new RuntimeException("Queue is empty");
        }
        if (stackPop.isEmpty()) {//如果已有入队元素,先倾倒
            synchronized (stackPush) {//锁住对象
                while (!stackPush.isEmpty()) {//直到倾倒完毕才可以释放对象锁
                    stackPop.push(stackPush.pop());
                }
            }
        }
        return stackPop.pop();
    }
    //返回队列队首元素,和poll出队类似
    public int peek(){
        if (stackPop.isEmpty() && stackPush.isEmpty()) {//如果队列为空
            throw new RuntimeException("Queue is empty");
        }
        if (stackPop.isEmpty()) {//如果已有入队元素,先倾倒
            synchronized (stackPush) {//锁住对象
                while (!stackPush.isEmpty()) {//直到倾倒完毕才可以释放对象锁
                    stackPop.push(stackPush.pop());
                }
            }
        }
        return stackPop.peek();
    }
}

 

你可能感兴趣的:(算法-队列)