我在前面已经介绍了栈和队列,以及栈和队列特殊的顺序存储结构。那么在我们的面试当中,面试官可能会出一些题目,比如用栈实现队列和用队列实现栈。本篇博客来具体实现以下这两个题目
1.用两个栈实现队列
假设我们有两个栈stack1和stack2.用这两个栈实现队列。这里讲解两种方案:
方案1
我们让入队操作在stack1中进行,而出队操作在stack2中执行,执行的方法如下:
1.入队:直接向stack1中入栈
2.出队:将stack1中的所有元素出栈,依次入栈到stack2中,然后弹出stack2中的栈顶元素,接着把stack2的元素出栈,再次入栈stack1。
思考:我们发现在出队操作中,来回的入栈和出栈比较繁琐,下面有一个更简便的方案
方案2
首先入队操作还是在stack1中完成,stack2用于出队,同时保证所有元素都在一个栈里,并且要遵守以下规则
入队:不管stack1是否为空栈,都将stack2中的元素压入stack1中
出队:若stack2不为空,则直接从stack2中弹出元素,若stack2为空,则把stack1中的所有元素倒入stack2中,然后弹出stack2的栈顶元素
方案2相对于方案1来说是更好的方案,下面我们用代码实现以下
package cn.csu;
/**
* Created by kuang on 2018/3/10.
*/
public class Stack2Queue {
private Stack stack1;
private Stack stack2;
private int maxLength;
public Stack2Queue(int capacity){
maxLength = capacity;
stack1 = new Stack(capacity);
stack2 = new Stack(capacity);
}
/**
* 入队操作
* @param item
* @return
*/
public boolean put(int item){
if(stack1.isFull() || maxLength == size()){
return false;
}
stack1.push(item);
return true;
}
/**
* 出队操作
* @return
*/
public int poll(){
if(!stack2.isEmpty()){
return stack2.pop();
}else{
while (!stack1.isEmpty()){
stack2.push(stack1.pop());
}
return stack2.pop();
}
}
public int size(){
return stack1.size() + stack2.size();
}
}
2.两个队列实现栈
下面介绍一下两个队列实现栈
栈的主要操作是入栈和出栈,其特点是先入后出
我们将两个队列定义为queue1和queue2
方案1
入栈和出栈都在queue1中进行,而queue2作为中转空间
入栈:直接入队queue1即可
出栈:把queue1中除了最后一个元素的其他元素都出队移动到queue2中,再将queue1剩下的元素出队,接着讲queue2中所有的元素移动到queue1中,这样就实现了出栈操作。
方案2
在方案1中,我们可以看出,即在出栈时要把queue中的元素移动到queue1中,那么每次进行出栈操作都要把元素移动回去,这样操作就显得比较麻烦。接下来看看方案2的思路:
入栈:两个队列哪个不为空,就把元素入队到哪个队列中,如果都为空,则任意选择一个队列入队(我这里假设选择的队列是queue1).
出栈:把不为空的队列除最后一个元素外的所有元素移动到另一个队列中,然后出队最后一个元素,那么这样就省去了方案1中每次都要把元素移动回去的操作
下面是实现代码:
package cn.csu;
/**
* Created by kuang on 2018/3/10.
*/
public class Queue2Stack {
private int maxLength;
private ArrayQueue queue1;
private ArrayQueue queue2;
public Queue2Stack(int capacity){
maxLength = capacity;
queue1 = new ArrayQueue(capacity);
queue2 = new ArrayQueue(capacity);
}
/**
* 入栈操作
* 两个队列哪个不为空,就把元素入队到哪个队列中,
* 如果都为空,则任意选择一个队列入队
* @param item
* @return
*/
public boolean push(int item){
if(size()== maxLength){
return false;
}
if(queue2.isEmpty()){
queue1.put(item);
}else{
queue2.put(item);
}
return true;
}
/**
* 出栈操作
* 把不为空的队列除最后一个元素外的所有元素移动到另一个队列中,然后出队最后一个元素
* @return
*/
public Object pop(){
if(size() == 0){
throw new IndexOutOfBoundsException();
}else{
if(queue2.isEmpty()){
while(queue1.size() >1){
queue2.put(queue1.poll());
}
return queue1.poll();
}else{
while(queue2.size()>1){
queue1.put(queue2.poll());
}
return queue2.poll();
}
}
}
public int size(){
return queue1.size() + queue2.size();
}
}