算法习题57:用两个栈实现队列

用俩个栈实现队列。
题目:某队列的声明如下:
template<typename T> class CQueue
{
17
public:
CQueue() {}
~CQueue() {}
void appendTail(const T& node);
void deleteHead();
// append a element to tail
// remove a element from head
private:
T> m_stack1;
T> m_stack2;
};
分析:从上面的类的声明中,我们发现在队列中有两个栈。
因此这道题实质上是要求我们用两个栈来实现一个队列。
相信大家对栈和队列的基本性质都非常了解了:栈是一种后入先出的数据容器,
因此对队列进行的插入和删除操作都是在栈顶上进行;队列是一种先入先出的数据容器,

我们总是把新元素插入到队列的尾部,而从队列的头部删除元素。

----------------------------------------------

难度不是很大,对于这种题目一般大家就注意细节问题:

(1)是否判断空的情况

(2)能否提高程序的通用性


下面段落引自一名面试官的小结(写得很棒):http://www.cnblogs.com/wanghui9072229/archive/2011/11/22/2259391.html

大多数人的思路是:始终维护s1作为存储空间,以s2作为临时缓冲区。

入队时,将元素压入s1

出队时,将s1的元素逐个“倒入”(弹出并压入)s2,将s2的顶元素弹出作为出队元素,之后再将s2剩下的元素逐个“倒回”s1

真正性能较高的,其实是另一个变种。即:

入队时,将元素压入s1

出队时,判断s2是否为空,如不为空,则直接弹出顶元素;如为空,则将s1的元素逐个“倒入”s2,把最后一个元素弹出并出队。

这个思路,避免了反复“倒”栈,仅在需要时才“倒”一次。但在实际面试中很少有人说出,可能是时间较少的缘故吧。


------------------------------------------------

这里用了模板来实现


//============================================================================
// Name        : StackQueue.cpp
// Author      : YLF
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include <vector>
using namespace std;

template <class T>
class Queue{
private:
	vector<T> stack1,stack2;
	int count;
public:
	Queue(){count = 0;}
	~Queue(){}

	void append(T x){
		stack1.push_back(x);
		count++;
	}

	T remove(){
		T re;
		if(stack2.size() != 0){
			re = stack2.at(stack2.size()-1);
			stack2.pop_back();
			count--;
		}
		else{
			/*这一步很关键!考虑问题全部全面 */
			if(stack1.size() == 0)
				return NULL;
			int i =0;
			for(i=stack1.size()-1;i>0;i--){
				re = stack1.at(i);
				stack1.pop_back();
				stack2.push_back(re);
			}
			re = stack1.at(0);
			stack1.pop_back();
			count--;
		}
		return re;
	}

	int size(){
		return count;
	}
};

int main() {

	Queue<char> queue;
	queue.append('a');
	queue.append('b');
	queue.append('c');
	queue.append('d');
	queue.append('f');

	cout<<"size="<<queue.size()<<endl;
	cout<<queue.remove()<<endl;
	cout<<queue.remove()<<endl;
	cout<<queue.remove()<<endl;
	cout<<queue.remove()<<endl;
	cout<<queue.remove()<<endl;
	cout<<"size="<<queue.size()<<endl;
	cout<<queue.remove()<<endl;
	cout<<"size="<<queue.size()<<endl;
	return 0;
}



细心的人会发现,我这里多remove()了一次,由于我判断来空,所以这里返回的NULL,所以不会报错

size=5
a
b
c
d
f
size=0

size=0



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值