利用两个栈实现一个队列

要想解决这个问题,我们首先需要明白栈和队列的特点。

  • 栈,先进后出;队列,先进先出
  • 当我们将所有元素入栈后,如何获取最先入栈的元素呢?此时,如果我们可以将栈中的元素倒置,就可以得到我们想要的结果。两种方法,第一种就是在入栈的时候将入栈元素保留一份副本,这种操作很麻烦,而且如何需要出栈还需要其他的辅助标识。第二种方法就是,将已入栈的元素全部倒出来,放入另一个容器中,而且这个容器能将之前栈中的元素倒置,刚好,栈就具备这种特性。因此,我们考虑采用两个栈,来实现一个队列。其中一个栈用来存储入队的元素,另一个栈用来存储待出栈的元素。

代码实现 

package leetcode.stack;
import java.util.Stack;

/**
 * @基本功能:利用两个栈实现一个队列
 * @program:summary
 * @author:peicc
 * @create:2019-10-07 14:46:39
 **/
public class QueueByStack<T> {
    private Stack<T> stack1=new Stack<>();// 储存入队的元素
    private Stack<T> stack2=new Stack<>();// 从此栈中获取队首元素
    /***
     * @函数功能:入队
     * @param x:
     * @return:void
     */
    public void add(T x){
        stack1.push(x);
    }
    /***
     * @函数功能:获取队首元素
     * @param :
     * @return:T
     */
    public T peek() throws Exception {
        if (stack2.isEmpty()) {
            while (!stack1.isEmpty()) {
                stack2.push(stack1.pop());
            }
        }
        if (!stack2.isEmpty()) {
            return stack2.peek();
        } else {
            throw new Exception("队列为空");
        }
    }
    /*** 
     * @函数功能:删除并返回队首元素
     * @param :
     * @return:T
     */
    public T poll() throws Exception {
        if (stack2.isEmpty()) {
            while (!stack1.isEmpty()) {
                stack2.push(stack1.pop());
            }
        }
        if (!stack2.isEmpty()) {
            return stack2.pop();
        } else {
            throw new Exception("队列为空");
        }
    }
}

使用测试

package leetcode.stack;

/**
 * @基本功能:
 * @program:summary
 * @author:peicc
 * @create:2019-10-07 15:14:03
 **/
public class TestQueueByStack {
    public static void main(String[] args) throws Exception {
        QueueByStack<Integer> queueByStack=new QueueByStack<>();
        for (int i = 0; i <3 ; i++) {
            queueByStack.add(i);
        }
        System.out.println(queueByStack.peek());
        System.out.println(queueByStack.poll());
        System.out.println(queueByStack.peek());
        System.out.println(queueByStack.poll());
        System.out.println(queueByStack.poll());
    }
}

实战演练

题目描述

 参考答案



import java.util.Scanner;
import java.util.Stack;

/**
 * @基本功能:利用两个栈实现一个队列
 * @program:summary
 * @author:peicc
 * @create:2019-10-07 14:46:39
 **/
public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int N=sc.nextInt();
        Stack<Integer> stack1=new Stack<>();
        Stack<Integer> stack2=new Stack<>();
        for (int i = 0; i <N ; i++) {
            String str=sc.next();
            if (str.contains("add")) {// add
                int x=sc.nextInt();// 读取待入队的数
                stack1.push(x);
            } else if (str.contains("peek")) {// peek
                if (!stack2.isEmpty()) {
                    System.out.println(stack2.peek());
                } else {// 当第二个栈为空时,将第一个栈中的元素弹出压入第二个栈中
                    while (!stack1.isEmpty()) {
                        stack2.push(stack1.pop());
                    }
                    System.out.println(stack2.peek());
                }
            } else {// poll
                if (!stack2.isEmpty()) {
                    stack2.pop();
                } else {// 当第二个栈为空时,将第一个栈中的元素弹出压入第二个栈中
                    while (!stack1.isEmpty()) {
                        stack2.push(stack1.pop());
                    }
                    stack2.pop();
                }
            }
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值