您的位置:首页 > 职场人生

【剑指offer】面试题7:用两个栈实现队列

2016-08-28 22:49 351 查看
题目给出的结构体:

template<typename T> class CQueue {
public:
CQueue();
~CQueue();
void appendTail(const T & node);
T deleteHead();

private:
stack<T> stack1;
stack<T> stack2;
};


要求实现以下两个函数

void appendTail(const T & node);
T deleteHead();


稍微想了一下:要实现的函数是队列的基本操作,所以我们的目标就是用两个栈实现队列的逻辑就好(有点废话)。存入数据(入队)的话,肯定是要push的,但是出队的话,因为队头在栈底,我们需要把栈中的元素一个一个pop出来才能访问到栈底,所以这时就需要另一个栈来存pop出的元素,实现如下:

我们选取stack1来存储入队元素,stack2来在出队时存队中元素。

template<typename T>
void CQueue<T>::appendTail(const T & node) {
stack1.push(node);
}


template<typename T>
T CQueue<T>::deleteHead() {
if (stack1.empty()) {
cout << "Blank!" << endl;
return -1;
}

while( !stack1.empty() ) {
stack2.push( stack1.top() );
stack1.pop();
}

T temp = stack2.top();
stack2.pop();

while( !stack2.empty() ) {
stack1.push( stack2.top() );
stack2.pop();
}

return temp;
}


顺便写一个print函数检验:

template<typename T>
void CQueue<T>::print() {
while( !stack1.empty() ) {
stack2.push( stack1.top() );
stack1.pop();
}

while( !stack2.empty() ) {
cout << stack2.top() << endl;
stack1.push( stack2.top() );
stack2.pop();
}
cout << endl;
}


自己实现之后,看书上的解法,发现其实可以优化,因为每次出队之后,不用急着将stack2中的元素放回stack1,而且错误情况的处理也不同:

template<typename T>
T CQueue<T>::deleteHead() {
if (stack2.empty()) {
while( !stack1.empty() ) {
stack2.push( stack1.top() );
stack1.pop();
}
}

if (stack2.empty()) {
cout << "Blank" << endl;
return -1;
}

T temp = stack2.top();
stack2.pop();
return temp;
}


扩展: 用两个队列实现一个栈

好吧,我先说一下自己笨笨的想法:

假设有两个队列q1,q2

入栈正常,就入第一个队列q1;

出栈,把q1中的元素逐个出队,每个出队元素入q2,然后q1只剩下一个元素就是栈顶元素,然后出队不入q2,再将q2中的元素全部入q1…

好吧大体思路是这样,但是考虑到之前书上的优化方法,我们在出栈的时候也可以不用再把q2的元素入q1,新来元素直接入q1就好,当再次有出栈请求,而q1为空的时候再将q2的元素入q1,如果q2也为空,说明队空
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  面试题