###题目:用两个栈实现一个队列。队列的声明如下,请实现它的两个函数appendTail 和deleteHead ,分别完成在队列尾部插入节点和在队列头部删除节点的功能。(java版:用两个栈,实现队列的从队尾插入元素offer()和从队头抛出元素poll()。)
思路:
(1)对于插入操作,栈与队列都是从队尾进行,因此一行代码就可以完成offer()
(2)对于弹出操作,队列先进先出从队头开始,而栈后进先出从队尾开始,要想取到队头元素,就得需要第二个栈stack2的协助:弹出时将stack1的元素依次取出放到stack2中,此时stack2进行弹出的顺序就是整个队列的弹出顺序。而如果需要插入,放到stack1中即可。
总结下,stack1负责插入,stack2负责弹出,如果stack2为空了,将stack1的元素依次弹出并存放到stack2中,之后对stack2进行弹出操作。
基于以上分析,java参考代码如下:
package chapter2;
import java.util.ArrayDeque;
public class P68_TwoStacksQueue {
private ArrayDeque<Integer> stack1=new ArrayDeque<>();//pushStack
private ArrayDeque<Integer> stack2=new ArrayDeque<>();//popStack
public void push(int val){
stack1.addFirst(val);
}
public int pop(){
if(stack1.isEmpty()&&stack2.isEmpty()){
throw new RuntimeException("Queue is empty!");
}else if(stack2.isEmpty()){
while (!stack1.isEmpty()){
stack2.addFirst(stack1.pollFirst());//stack1--->stack2 all.
}
}
return stack2.pollFirst();
}
public int peek(){
if(stack1.isEmpty()&&stack2.isEmpty()){
throw new RuntimeException("Queue is empty!");
}else if(stack2.isEmpty()){
while (!stack1.isEmpty()){
stack2.addFirst(stack1.pollFirst());//stack1--->stack2 all.
}
}
return stack2.peekFirst();
}
public static void main(String[] args) {
P68_TwoStacksQueue myque=new P68_TwoStacksQueue();
myque.push(1);
myque.push(2);
System.out.println(myque.pop());
System.out.println(myque.pop());
myque.push(3);
myque.push(4);
System.out.println(myque.peek());
System.out.println(myque.pop());
System.out.println(myque.pop());
//System.out.println(myque.pop());//Exception
}
}
C++分析如下:
template <typename T> class CQueue
{
public:
CQueue(void);
~CQueue(void);
void appendTail(const T& node);
T deleteHead();
private:
stack<T> stack1;
stack<T> stack2;
};
分析:当stack2 不为空时,在stack2 中的栈顶元素是最先进进入队列的元素,可以弹出。当stack2 为空时,我们把stack1 中的元素逐个弹出并压入stack2。由于先进入队列的元素被压到stack1 的底端,经过弹出和压入操作之后就处于stack2 的顶端,又可以直接弹出。
C++参考代码如下:
template<typename T> void CQueue<T>::appendTail(const T& element)
{
stack1.push(element);
}
template<typename T> void CQueue<T>::deleteHead()
{
if(stack2.size()<=0)
{
while(stack1.size()>0)
{
T& data=stack1.top();
stack1.pop();
stack2.push(data);
}
}
if(stack2.size()==0)
throw new exception("queue is empty");
T head==stack2.top();
stack2.pop();
return head;
}
用两个队列实现一个栈
java参考代码如下:
package chapter2;
import chapter4.P151_MirrorOfBinaryTree;
import java.util.ArrayDeque;
public class P68_TwoQueuesStack {
private ArrayDeque<Integer> queue=new ArrayDeque<>();
private ArrayDeque<Integer> help=new ArrayDeque<>();
public void push(int val){
queue.addLast(val);
}
public int pop(){
if(queue.isEmpty()){
throw new RuntimeException("Stack is empty!");
}
while (queue.size()>1){
help.addLast(queue.pollFirst());//queue-->help
}
int res=queue.pollFirst();
swap();
return res;
}
public int peek(){
if(queue.isEmpty()){
throw new RuntimeException("Stack is empty!");
}
while (queue.size()>1){
help.addLast(queue.pollFirst());//queue-->help
}
int res=queue.pollFirst();
help.addLast(res);
swap();
return res;
}
public void swap(){//call by value !!
ArrayDeque<Integer> temp;
temp=queue;
queue=help;
help=temp;
}
public static void main(String[] args) {
P68_TwoQueuesStack stack= new P68_TwoQueuesStack();
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
System.out.println(stack.pop());
System.out.println(stack.pop());
System.out.println(stack.pop());
System.out.println(stack.pop());
}
}
测试用例:
a.往空的队列里添加、删除元素。
b.往非空的队列里添加、删除元素。
c.连续删除元素直至队列为空。