【栈和队列】定义一个类,实现一个队列,队列里有两个栈,此类支持队列的基本操作

功能需求

        在一个类中,定义两个公共访问的栈,这两个栈通过交互形成一个队列,保持先进先出的特点并且支持入栈add、poll、peek的操作。同时算法复杂度不能太高。

详细解析

        栈的特点是先进后出,而队列的特点是先进先出,我们把两个栈首尾相接起来,一个压入栈,一个弹出栈,就可以实现相应的队列的操作。具体实现是定义一个压入栈stackPush,在压入数据时只往这个栈中压入数据和一个退出栈stackPop弹出数据只从这个栈中弹出,分别对应队列的入列和出列。

        因为数据压入栈的时候,顺序是先进后出的。那么只要吧stackPush的数据在压入stackPop中,顺序就变了回来。例如,将1~5依次压入stackPush栈中,那么在stackPush栈中栈顶到栈底依次为5~1,将此时的5~1倒入stackPop中,那么stackPop栈中从栈顶到栈底的数据就会依次是1~5.再从stackPop弹出时,就会像队列一样,其效果图如下

 

        这样看起来是非常简单的,实际上的要求将会有以下两点:1、stackPush中的数据必须要一次性全部压入stackPop中;2、如果stackPop栈中已经存在元素数据,是不能给stackPop栈中压入数据的。这两点都是会导致错误的。

        如果违反了1原则:举个例子,1~5依次压入stackPush,stackPush栈顶到栈底的元素分别为5~1,从stackPush压入stackPop栈中时,只将栈顶的5和4压入stackPop,stackPush栈还有3,2,1三个元素存在没有压入。此时用户想要弹栈操作,那么4将先被弹出。这样与预想的队列顺序就不一致了。

        如果违反了规则2:将1-5依次压入stackPush栈中,stackPush栈中从栈顶到栈底依次为5~1,stackPush栈中的元素全部倒入stackPop栈中压栈处理,所以stackPop栈中的元素从栈顶到栈底依次为1~5,又在此时压入6~10到stackPush,stackPop不为空,stackPush不能将其数据压入stackPop。如果违反了强行压入,那么stackPop栈中从栈顶到栈低的元素就会变为6~10,1~5,那么此时再弹出栈中元素就会把6先弹出栈,不符合队里的规则。

        在调用add(), poll(),peek三种方法中任何一种发生时"压入"元素时的行为都是可以的,前提条件是不违反以上两点。具体请看以下代码:

代码实现

package com.hekaikai666.test2;

import java.util.Stack;

/**
 * 
 * @author hekaikai666
 * @time 2018年8月23日下午8:40:35
 **/
public class StackTo {
    // 栈一存储数据
    private Stack<Integer> stackPush;
    // 栈二存储栈一中出来的数据
    private Stack<Integer> stackPop;

    /**
     * 单例模式实例化栈(构造方法)
     */
    public StackTo() {
	super();
	this.stackPush = new Stack<Integer>();
	this.stackPop = new Stack<Integer>();
    }

    /**
     * poll()方法操作栈中数据
     */
    public int poll() {
	// 判断两个栈是否都为空
	if (stackPop.isEmpty() && stackPush.isEmpty()) {
	    // 抛出一个运行时异常
	    throw new RuntimeException("Your Stack is empty");
	    // 如果只有存入栈为空
	} else if (stackPop.isEmpty()) {
	    // 循环弹出stackPush中的元素并压入stackPop栈中,知道stackPush栈为空
	    while (!stackPush.isEmpty()) {
		stackPop.push(stackPush.pop());
	    }
	}
	// 返回此栈值
	return stackPop.pop();
    }
    public int peek() {
	// 判断两个栈是否都为空
	if (stackPop.isEmpty() && stackPush.isEmpty()) {
	    // 抛出一个运行时异常
	    throw new RuntimeException("Your Stack is empty");
	    // 如果只有存入栈为空
	} else if(stackPop.isEmpty()) {
	    // 循环弹出stackPush中的元素并压入stackPop栈中,知道stackPush栈为空
	    while (!stackPush.isEmpty()) {
		stackPop.push(stackPush.pop());
	    }
	}
	// 返回此栈值
	return stackPop.peek();
    }
}

总结分析

        我们都能想到两个先进先出的栈首尾相接能实现一个队列,但是在这两个栈中的细节,比如说他们要是没有完全弹出元素,那么会导致栈种元素混乱,之后就不符合队列的要求了,其实实现很简单,思想很重要

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值