用两个栈实现队列 ——Java从0开始学习系列之路(3)

前言:

博主现在坐在教室,本来打算写《代码面试指南》中的第4题,但是现在很累,脑瓜转不动了,再写代码的话,效率太低了,不如把第二题记录起来,go,go,go..!

 

用两个栈组成的队列

题目

    编写一个类,用两个栈实现队列,支持队列的基本操作(add,poll,peek)

分析:

我与大家一起分析一下,这题其实就是考察特殊数据结构的设计能力,自己编写一个特殊的队列,这个队列的方法中除了要有普通队列的基本操作之外,还要有两个栈成员,并在这两个栈的基础上进行功能的实现。

设两个栈分别为stack1, stack2。 假如1,2.3.4.5分别入栈,那么由于栈的先进后出性,出栈顺序应该是5.4.3.2.1。但是队列是先进先出,其出队顺序应该是1.2.3.4.5。那么我们怎么办呢?其实也挺容易想到的,就是再拿一个栈stack2, 把stack1的顺序全部弹出到

stack2,  此时stack2 中从栈顶到栈底的元素就分别是5.4.3.2.1了,此时元素的出栈顺序就和队列中的出队顺序一样了。OK,,到这边是不是觉得很简单,跃跃欲试啦,但是其实有个地方很容易出错的: 

也就是只有stack2为空时,才能从stack1把元素倒入stack2,而且必须一次性全部倒入stack2......

假设没有全部倒入,而是只倒入了5.4(如图1)在这之后,如果我们执行出队操作,那么出队的元素就会是5,但实际上率先出队的应该是1.

 

假设在stack2不为空的时候,就从stack1把元素全部倒入stack2(如图二).。此时stack2中的元素还未空,stack1有两个元素分别是7.6,如果此时把7.6倒入stack1,在这之后若进行队列的出队操作,那么率先出队的元素会是6,但实际上应该是1。

          stack1             stack2                                                                         stack1                   stack2

            5                                                                                                                                           1

            4                                                                                                                                           2

            3                                                                                                                                           3

            2                      4                                                                                   7                              4

            1                      5                                                                                   6                               5

                (图   1)                                                                                             (图     2)

 

心得:先自己思考解决方法,思考不出来的话才看下书上的思路分析,但是不要看代码。

           看完思路分析后,自己动手实现,看看自己能不能成功实现。

            如果实现不出来,再看书上的代码,看完后再自己动手实现(到了这步就万万不能再看书上的代码了,必须自己实现)

附Java代码:

package code_180;

import java.util.*;
import java.util.Stack;
public class TwoStack {

	private  Stack<Integer> Stack1;
	private  Stack<Integer> Stack2;
	
	TwoStack(){
		
		this.Stack1 = new Stack<Integer>();
		this.Stack2 = new Stack<Integer>();
	}
	public void add(int newNum) {
		
		this.Stack1.push(newNum);

	}
	public void poll() {
		
		if(this.Stack2.empty()) {
			
			while(this.Stack1.empty() == false) {
				
				int tempNum = this.Stack1.peek();
				this.Stack1.pop();
				this.Stack2.push(tempNum);
				
			}
			
			this.Stack2.pop();
		}
		else
			this.Stack2.pop();
	}
	
	public int peek() {
		
		if(this.Stack2.empty()) {
			
			while(this.Stack1.empty() == false) {
				
				int tempNum = this.Stack1.peek();
				this.Stack1.pop();
				this.Stack2.push(tempNum);
				
			}
			
			return this.Stack2.peek();
		}
		else
			return this.Stack2.peek();
	
	}
	
	//int []arrayTest = {1,2,3,4,5};
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		int [] arrayTest = {1,2,3,4,5};
		TwoStack myQueue = new TwoStack();
		for(int i = 0 ;i<arrayTest.length; i++) {
			
			myQueue.add(arrayTest[i]);
			
		}
		
		myQueue.poll();
		
		System.out.println(myQueue.peek());
	
		
		
     
	}
	
	

}

学习到的关于Java中的新知识:

如果类中含有某个类,我必须在构造函数中显示的new出个实例,不然会抛出异常,这与c++中的不一样的是,C++中string的构造函数会被自动调用,会自动创建实例,一开始我两者类比了,但是出错了,虽然Stack是包中的类,但是也必须自己在构造函数中显示的new一个对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值