1. 用两个栈实现队列

题目描述(两个栈=>队列):
剑指offer面试题第九题:用两个栈实现队列的基本操作(队尾插入,队头弹出,显示队头)

题目分析和解答:
用两个栈实现队列

这里借用原书中的话,他教给我们如何先用实例分析题目,然后再抽象成解法。分析过程参考原书和上图,最后总结出,
a)删除一个元素的步骤:
当stack2不为空时,在stack2的栈顶元素就是最先进入队列的元素,可以弹出。
当stack2为空时,我们把stack1的元素逐个弹出并压入stack2.由于先进入队列的元素被压到stack1的底部,经过弹出和压入操作之后,就处于stack2的顶端了,又可以直接弹出。
b)插入一个元素的步骤:
直接把它插入到stack1中。
c)显示队列头部:
当stack2不为空时,栈顶元素就是队列的头部,直接显示。
当stack2为空,我们把stack1的元素逐个弹出并压入stack2,再显示stack2的栈顶元素,如果此时stack2还是空,那说明stack1之前就是空的,抛出“队列为空”。

# include <iostream>
# include <stack>

using namespace std;

/*
暂时先定义成 接受int 类型的栈
*/

class myQueue{
    public:
        // constructure
        myQueue(stack<int> stack1, stack<int> stack2);
        ~myQueue();
        // number function: push() 将元素压入栈
        void push(int node);
        // number function: pop() 弹出栈顶的元素,且不返回改元素
        void pop(void);
        // number function: peek() 返回栈顶的元素
        int front(void);
    private:
        stack<int> stack1;
        stack<int> stack2;
};
// number function: push() 将元素压入栈
void myQueue::push(int node){
    stack1.push(node);
}
// number function: pop() 弹出栈顶的元素,且不返回改元素
void myQueue::pop(void){
    // 将stack1中的元素都压入stack2中
    if (stack2.empty()){
        while(!stack1.empty()){
        stack2.push(stack1.top());
        stack1.pop();
        }
    }
    if(stack2.empty()){
        std::cout << "Your queue is empty." << endl;
        return;
    }
    stack2.pop();
}
int myQueue::front(void){
    if (stack2.empty()){
        while(!stack1.empty()){
        stack2.push(stack1.top());
        stack1.pop();
        }
    }
    if(stack2.empty()){
        throw "Your queue is empty.";
    }
    return stack2.top();
}
myQueue::myQueue(stack<int> stack1, stack<int> stack2):stack1(stack1),stack2(stack2){

}
myQueue::~myQueue(){

}

int main(int argc, char const *argv[])
{
    stack<int> stack_1, stack_2;
    myQueue myqueue(stack_1, stack_2);
    for(int i=0; i<10; i++){
        myqueue.push(i);
    }
    for(int i=0; i<10; i++){
        cout << myqueue.front() << endl;
        myqueue.pop();
    }

    return 0;
}

2. 两个队列实现栈

剑指offer面试题第九题扩展:用两个队列实现队栈的基本操作(入栈,出栈,显示栈顶)
题目分析和解答
用两个队列实现栈
如上图所示,分析过程参考原书,我们自己规定,每次插入新元素到queue1中。如果把queue1中的元素依次从队头弹出,从queue2的队尾加入,相对顺序不变。比如加入a,b,c, 最新加入的是c, 如果要弹出栈顶元素也就是弹出队尾的元素,此时可以依次把queue1的元素依次进入queue2,直到queue1中还剩一个元素(他必定是最新加入的元素,在队尾),把它弹出。然后在依次把queue2的元素,加入到queue1中。
a)删除一个元素的步骤:
如果queue1为空,则抛出“队列为空”。
如果queue1不为空,依次把queue1的元素依次进入queue2,直到queue1中还剩一个元素(他必定是最新加入的元素,在队尾),把它弹出。然后在依次把queue2的元素,加入到queue1中。
这样我们就保证了,每次删除数据后,数据都放在queue1,queue2只是起缓存的作用。
b)插入一个元素的步骤:
直接插入到queue1。
c)显示栈顶元素:
如果stack1不为空,直接显示队尾元素。
如果stack1为空,抛出“队列为空”。

# include <iostream>
# include <queue>

using namespace std;
class myStack{
    public:
        myStack(queue<int> queue1, queue<int> queue2);
        ~myStack();
        void push(int node);
        int top(void);
        void pop(void);
    private:
        queue<int> queue1;
        queue<int> queue2;
};
myStack::myStack(queue<int> queue1, queue<int> queue2):queue1(queue1), queue2(queue2){}

myStack::~myStack(){}

// 把元素压入队列1中
void myStack::push(int node){
    queue1.push(node);
}

// 把元素先从队列1中,从头出队依次进入队列2,直到队列1还剩一个元素,把这个元素弹出,就是栈顶的元素
// 然后再把队列2的元素依次出队放入到队列1中
void myStack::pop(void){
    if (queue1.empty()){
        cout << "Your stack is empty!" << endl;
        return;
    }
    while(queue1.size() != 1){
        queue2.push(queue1.front());
        queue1.pop();
    }
    queue1.pop();
    while(!queue2.empty()){
        queue1.push(queue2.front());
        queue2.pop();
    }
    return;
}

int myStack::top(void){
    if (queue1.empty()){
        cout << "Your stack is empty!" << endl;
        return -1;
    }else{
        return queue1.back();
    }

}
int main(int argc, char const *argv[])
{
    queue<int> queue_1, queue_2;
    myStack mystack(queue_1, queue_2);
        for(int i=0; i<10; i++){
        mystack.push(i);
    }
    for(int i=0; i<10; i++){
        cout << mystack.top() << endl;
        mystack.pop();
    }
    mystack.pop();
    mystack.pop();
    return 0;
}