用两个栈实现一个队列

12 篇文章 0 订阅
12 篇文章 0 订阅

最近有人问我这样 一道面试题:请用两个栈实现一个队列的功能。

老实讲这确实是一道非常经典的面试题,我记得我当初找工作参加面试时,就遇到过不止一次。在此总结一下这道题的思路及解法。

首先我们先来看一下怎样用两个栈实现一个队列的功能。栈与队列都是线性结构,都可以用顺序表或链表来实现,其最大的区别在于它们的逻辑特性不同。对于栈来说,它是一个先进后出的线性表,最开始进入栈中的元素总是最后一个出来。而队列恰好相反,它是先进先出的线性表,最开始进入队列的元素一定是第一个出来的。所以我们要用栈实现队列的功能,就必须通过一种方式将先进后出转化为先进先出,这样就能模拟出队列的逻辑特性了。

面对这道题时,很多人都会有这样的思路:

使用两个栈,一个栈(不妨叫做s1)用来存放数据,一个栈(不妨叫做s2)用来作为缓冲区。当入队列操作时,将元素压入栈s1中;当初队列操作时,将s1的元素逐个弹出并压入s2,将s2的顶元素弹出作为出队元素,然后再将s2中的元素逐个弹出并压入s1中。如图所示:

但是该方法存在一些冗余操作。细心的朋友一定会看出,出队列操作的第二步“出栈”完成后,没有必要将栈s2中的数据全部倒回栈s1中,因为下次的出队列操作还要在s2中完成,而且下一次的出队列操作取出的元素仍是当前s2的栈顶元素。因此该算法可以改进一下:

入队操作时,将元素压入栈s1中;出队操作时,判断s2是否为空,如果s2不为空,则直接取出s2的栈顶元素;如果s2为空,则将s1的元素逐个弹出并压入s2,再取出s2的栈顶元素即可。

本题的代码如下:

sqStack s1, s2;    /*定义两个栈s1和s2,用它们实现一个队列*/

int initQueue() {
	if (initStack(&s1) && initStack(&s2))  {
		return 1;
	}
	return 0;
}

int EnQueue(int x) {
	if (Push(&s1,x)) {
		return 1;		/*入队列,将x压入栈s1*/
	}
	return 0;
}

int DeQueue(int *x) {
	int e;
	if (s2.base == s2.top) {
		/*栈s2为空的情况*/
		if (s1.top == s1.base) {
			return 0;
		} else {
			while (Pop(&s1,&e)) {
				Push(&s2,e);
			}
		}
	} 
	Pop(&s2,x);		 /*出队列,从栈s2中取出数据*/
	return 1;
}

其实本题最好用C++实现,这样定义一个类queue,并在类中实现方法EnQueue,DeQueue等,实现的方式则是通过两个堆栈模拟一个队列的操作。

这样就相当于一个适配器模式,将Class stack封了一层接口,并通过一些算法实现队列的操作。




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值