剑指offer第二版-用队列实现一个栈

本系列导航:剑指offer(第二版)java实现导航帖

用队列实现一个栈
题目要求:用两个队列,实现栈的从队尾插入元素push()和从队尾抛出元素pop()
相关:用栈实现队列

思路(书中标准解法:用两个队列实现一个栈):
(1)对于插入操作,栈与队列都是从队尾进行,因此很容易完成。
(2)对于弹出操作,队列从队头开始,而栈从队尾开始,要想取到队尾元素,需要第二个队列的协助:假设queue1不为空,queue2为空,将queue1的原书依次取出放到queue2中,同时判断,当queue1的长度为1时,不要将该元素放到queue2中,而是直接取出丢弃,此时即完成了栈的弹出操作。也就是说,弹出一个元素,其他元素的存储位置就会从本队列移动到另一个队列中。
总结下,运作过程中,queue,queue2一定至少一个为空。插入操作选择queue1,queue2中不为空的那个队列插入(如果都为空,随意选择一个),弹出时将不为空的队列除最后一个队列的其他元素依次取出放到另一个队列中,而将最后那一个元素取出丢弃即可。

代码:

package chapter2;
import java.util.LinkedList;
import java.util.Queue;
/**
 * Created by ryder on 2017/6/21.
 * 用队列实现一个栈
 */

//用两个队列实现一个栈
class MyStack<T>{
    private Queue<T> queue1 = new LinkedList<>();
    private Queue<T> queue2 = new LinkedList<>();
    public void push(T data){
        if(!queue2.isEmpty())
            queue2.offer(data);
        else
            queue1.offer(data);
    }
    public T pop(){
        if(!queue2.isEmpty()){
            int size = queue2.size();
            for(int i=0;i<size-1;i++)
                queue1.offer(queue2.poll());
            return queue2.poll();
        }
        else if(!queue1.isEmpty()){
            int size = queue1.size();
            for(int i=0;i<size-1;i++)
                queue2.offer(queue1.poll());
            return queue1.poll();
        }
        else
            return null;
    }
}
public class P71_StackWithTwoQueues {
    public static void main(String[] args) {
        test1();
    }
    public static void test1() {
        MyStack<Integer> myStack = new MyStack<>();
        System.out.println(myStack.pop());
        myStack.push(1);
        myStack.push(2);
        myStack.push(3);
        System.out.println(myStack.pop());
        System.out.println(myStack.pop());
        myStack.push(4);
        System.out.println(myStack.pop());
        System.out.println(myStack.pop());
        System.out.println(myStack.pop());
    }
}

运行结果

null
3
2
4
1
null

改进解法思路(用一个队列实现一个栈):
(1)对于插入操作,栈与队列都是从队尾进行,一行代码解决。
(2)对于弹出操作,假设队列长度为n(假设存储内容为头2,5,1,3,4尾),对从队头poll出来的元素执行offer存入队尾,依次进行n-1次poll与offer(此时存储的内容为头4,2,5,1,3尾),然后再执行一次poll(此时为2,5,1,3),即完成了自实现栈的弹出。
【相较于上面的标准解法,此解法时间一样,但空间却能节省一半】

代码:

package chapter2;
import java.util.LinkedList;
import java.util.Queue;

/**
 * Created by ryder on 2017/6/21.
 * 用队列实现一个栈
 */

//用一个队列实现一个栈
class MyStack2<T> {
    private Queue<T> queue = new LinkedList<>();

    public void push(T data) {
        queue.offer(data);
    }
    public T pop() {
        if(queue.isEmpty())
            return null;
        else{
            int size = queue.size();
            for (int i = 0; i < size - 1; i++)
                queue.offer(queue.poll());
            return queue.poll();
        }
    }
}

public class P71_StackWithTwoQueues {
    public static void test2() {
        MyStack2<Integer> myStack = new MyStack2<>();
        System.out.println(myStack.pop());
        myStack.push(1);
        myStack.push(2);
        myStack.push(3);
        System.out.println(myStack.pop());
        System.out.println(myStack.pop());
        myStack.push(4);
        System.out.println(myStack.pop());
        System.out.println(myStack.pop());
        System.out.println(myStack.pop());
    }
    public static void main(String[] args) {
        test2();
    }
}

运行结果

null
3
2
4
1
null
    原文作者:ryderchan
    原文地址: https://www.jianshu.com/p/99d919146bf5#comments
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞