前言:
博主现在坐在教室,本来打算写《代码面试指南》中的第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一个对象。