1.原理分析:
队列的主要操作有两个:入队操作和出队操作,出队时从队头出,入队是从队尾插入,入队的操作和入栈的操作类似,而最关键的问题是出队操作,要出队列的是队列的第一个元素,而出栈的是栈的栈顶元素,所以我们可以这样:
假设两个栈A和栈B,A主要用来处理入队操作,B用于处理出队操作。入队操作和入栈操作类似,直接将元素压入栈即可。出队的时候,实现我们假设栈B为空,则要把栈A的第一个元素(即栈底元素)弹出,直接从A弹出这是不可能的,但如果我们把栈A里面的元素的顺序逆过来,这样直接用栈弹出栈顶元素即可,所以我们可以把栈A的元素全部弹出来,并俺顺序压入栈B中,这样每次栈B弹出的栈顶元素就是栈A相对应的栈底元素,就是出队操作。若B不为空,则代表之前从A复制过来的元素还没有完全弹出,要出栈的时候直接弹出即可。若栈B的元素都弹出来了,就需要从A中补充。
2.总结操作就是:
入队:将元素进栈A
出队:判断栈B是否为空,如果为空,则将栈A中所有元素pop,并push进栈B,栈B出栈;如果不为空,栈B直接出栈。
3.Java代码实现
import java.util.Stack; public class StacksToQueue { Stack<Integer> stack1=new Stack<Integer>() ; Stack<Integer> stack2=new Stack<Integer>(); public void addToTail(int x)//添加元素到队尾 --进队--- { stack1.push(x); } public int deleteHead()//删除对首 --出队--- 不需是队不为空才能删除呀~~~~ { if( pSize()!=0)//队列不为空 { if(stack2.isEmpty())//若stack2为空,则把stack1全部加入stack2 stack1ToStack2(); return stack2.pop(); } else { System.out.println("队列已经为空,不能执行从队头出队"); return -1; } } public void stack1ToStack2()//把stack1全部放入stack2 { while(!stack1.isEmpty()) stack2.push(stack1.pop()); } public int pSize()//队列size() { return stack1.size()+stack2.size();//两个都为空队列才是空 } }
入栈:将元素进队列A
出栈:判断队列A中元素的个数是否为1,如果等于1,则出队列,否则将队列A中的元素 以此出队列并放入队列B,直到队列A中的元素留下一个,然后队列A出队列,再把 队列B中的元素出队列以此放入队列A中。
3.Java代码实现: import java.util.LinkedList; public class QueuesToStack { LinkedList<Integer> queue1=new LinkedList<Integer>(); LinkedList<Integer> queue2=new LinkedList<Integer>(); public void push(int value)//入栈 { queue1.addLast(value); } public int pop()//出栈 必须是非空的栈才能出栈啊 { if(sSize()!=0)//栈不为空 { //移动一个队的n-1个到另一个中 if(!queue1.isEmpty())//q1 空 { putN_1ToAnthor(); return queue1.removeFirst(); } else //q2 空 { putN_1ToAnthor(); return queue2.removeFirst(); } } else { System.out.println("栈已经为空啦,不能出栈"); return -1; } } public int sSize() { return queue1.size()+queue2.size(); } public void putN_1ToAnthor()//从非空中出队n-1个到另一个队列 因为队列总是一空一非空 { if(!queue1.isEmpty()) { while(queue1.size()>1) { queue2.addLast(queue1.removeFirst()); } } else if(!queue2.isEmpty()) { while(queue2.size()>1) { queue1.addLast(queue2.removeFirst()); } } } }