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;
}
京公网安备 11010502036488号