题目
用两个栈实现一个队列,实现在队列尾部插入节点和在队列头部删除节点的功能。
一、什么是队列和栈?
1.1栈
栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。 它按照后进先出(LIFO—last in first out)的原则存储数据,先进入的数据被压入(push)栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出(pop)数据(最后一个数据被第一个读出来)。 栈在计算机领域被广泛应用,比如:操作系统会给每个线程创建一个栈用来存储函数调用时各个函数的参数、返回地址及临时变量等。
1.2队列
队列是一种特殊的线性表,它只允许在表的前端(队头)进行删除操作,在表的后端(队尾)进行插入。 故队列又称为先进先出(FIFO—first in first out)线性表。
二、具体实现
2.1 思路分析
(a)在stack1中依次插入a、b、c,stack2为空
(b)现在从队列中删除一个元素,按照队列先入先出的规则,最先删除的应该是a。 但是a在栈底不能直接删除,这时候可以借助stack2,将元素逐个弹出(pop)并压入(push)stack2,则元素在stack2中的顺序{从c、b、a}正好和stack1中相反,此时就可以弹出stack2的栈顶a,如图b。
(c)如果想继续删除队列头部,按照最开始的顺序,b比c早进入队列,此时应该删除b。b正好在stack2的栈顶,只需要弹出stack2的栈顶即可。如图c。
这样就可以总结出一个删除的步骤: 1、当stack2不为空时,stack2就是栈顶就是最先进入队列的元素,可以弹出。 2、当stack2为空时,将stack1中的元素逐个弹入stack2中,由于先进入队列的元素被压到stack1栈底,经过弹出和压入操作后位处stack2栈顶,就可以直接弹出。
(d)接下来插入一个元素d,把它压入stack1。
(e)现在考虑删除一个元素,此时stack2不为空,直接弹出c,而c确实比d先进入队列,因此也是正确的。
2.2代码实现 代码如下:
import java.util.*;
import java.util.Stack;
public class CQueue{
Stack<Integer> stack1 = new Stack<Integer>();
Stack<Integer> stack2 = new Stack<Integer>();
public void push(int node){
stack1.push(node);
}
public int pop(){
if(stack2.isEmpty()){
//将第一个栈中内容弹出放入第二个栈中
while(!stack1.isEmpty()){
stack2.push(stack1.pop());
}
}
if(stack2.isEmpty()){
Throw new Exception(queue is empty!);
}
int head = stack2.pop();
return head;
}
}