面试题9:用两个栈实现队列。队列声明如下,实现它的appendTail和deleteHead函数,分别表示在队尾插入节点和在队列头删除节点。
template <typename T> class CQueue {
public:
CQueue();
~CQueue();
void appendTail(const T &node);
T deleteHead();
private:
stack<T> stack1;
stack<T> stack2;
};
首先分析一下往该队列中插入和删除元素的过程,首先插入一个元素a,不妨把它插入stack1,再向stack1中压入两个元素b、c,此时stack2是空的。此时,我们想从队列中删除一个元素,由于a先进,因此a先出,但a在栈底,我们可以把stack1中所有元素依次先出栈再压入stack2,完成后stack1为空,而stack2的栈顶就是a了。如我们还想出队列,继续弹出stack2的栈顶元素即可。因此,当我们想出队列且stack2不为空时,直接弹出stack2的栈顶元素即可;当stack2为空时,将stack1中所有元素依次弹出并压入stack2,之后再弹出即可。
考虑继续向队列插入元素,我们直接向stack1插入元素即可:
#include <iostream>
#include <stack>
using namespace std;
template <typename T> class CQueue {
public:
void appendTail(const T& node);
T deleteHead();
private:
stack<T> stack1;
stack<T> stack2;
};
template <typename T> T CQueue<T>::deleteHead() {
if (stack2.size() == 0) {
while (stack1.size() > 0) {
stack2.push(stack1.top());
stack1.pop();
}
}
if (stack2.size() == 0) {
throw exception("empty queue");
}
T res = stack2.top(); // 此处不能定义为引用以提高效率,因为栈顶元素在下句代码被弹出
stack2.pop();
return res;
}
template <typename T> void CQueue<T>::appendTail(const T &node) {
stack1.push(node);
}
int main() {
CQueue<int> q;
q.appendTail(1);
q.appendTail(2);
q.appendTail(3);
q.appendTail(4);
q.appendTail(5);
cout << q.deleteHead() << endl;
}
相关题目:
1.用两个队列实现一个栈。分析:我们先往栈中压入元素a,不妨将a放入queue1中,接下来往栈中压入元素b、c,我们将b、c都存入queue1中,这样a位于queue1的队列头,b、c紧随其后。当我们想弹出一个元素时,如上例,应该弹出c,我们就可以把queue1中元素依次出队列再入队列queue2,这样c是queue1中最后一个出队列的,将c删除即可,这样,queue2中从头到尾元素为a、b,弹出b时重复以上步骤即可。当我们想压入元素d时,直接放在有元素的队列的队尾即可,这样再出栈时,按以上步骤出栈的还是d,符合栈的后进先出特点。
#include <iostream>
#include <deque>
using namespace std;
template <typename T> class CStack {
public:
void push(const T &);
T pop();
private:
deque<T> que[2];
};
template <typename T> void CStack<T>::push(const T& t) {
int i = 0;
if (que[i].size() == 0) { // 向有元素的队列插入
i = 1 - i;
}
que[i].push_back(t);
}
template <typename T> T CStack<T>::pop() {
int i = 0;
if (que[i].size() == 0) {
i = 1 - i;
}
if (que[i].size() == 0) {
throw exception("empty stack");
}
while (que[i].size() != 1) {
que[1 - i].push_back(que[i].front());
que[i].pop_front();
}
T res = que[i].front();
que[i].pop_front();
return res;
}
int main() {
CStack<int> s;
s.push(1);
s.push(2);
s.push(3);
s.push(4);
cout << s.pop() << endl;
}