两个栈实现一个队列

用两个栈实现一个队列主要需要实现的是队列的入队和出队操作。针对这一问题有以下几种方案

方案一

用一个栈来维护队列的出队,入队操作,具体实现方法如下:

入队:将元素压入第一个栈中

出队:

(1)将第一个栈中的元素(除栈底元素外)依次导入第二个栈中

(2)将第一个栈中剩下的那个元素弹出

(3)将第二个栈中的元素依次倒回到第一个栈中

方案二

第一个栈管理队列的入队,第二个栈管理队列的出队操作

和方案一不同的是,步骤(2)后,不需要执行步骤(3),只有当要执行入队操作时,才执行步骤(3)


比较:

方案二比方案一好的一点是不需要每次执行完出队操作后,都将第二个栈中的元素倒回到第一个栈中,因为不是每次都需要入队操作,可以节省时间。


方案三

两个栈共同维护栈的入队出队操作,第一个栈执行入队出队操作,第二个栈执行出队操作

入队:将元素压入第一个栈中(第一个栈中栈顶元素一定是队列的队尾元素,是队列中最后一个进入队列中的元素)

出队:

(1)判断两个栈是否都为空,若都为空,则结束程序,若有一个栈不为空,则执行一下步骤

(2)若第二个栈不为空,则将第二个栈中栈顶元素弹出(因为第二个栈的栈顶元素是队列中最先进入队列中的元素,相当于对头的元素,出队时将队头元素出队)

(3)若第二个栈为空,那么将第一个栈中的元素(除栈底元素)依次导入第二个栈中,删除第一个栈中的元素


方案三代码:

两个栈实现一个队列
template<class T>
class Queue
{
public:
	void Push(const T& d)
	{
		sPush.push(d);
	}
	void Pop()
	{
		if (Size())//若两个栈都为空
		{
			return;
		}
		if (sPop.empty()) //若第二个栈为空
		{
			ExChange(sPush, sPop);//将第一个栈中元素导入到第二个栈中
		}
		sPop.pop();//栈顶元素弹出
	
	}
	T& Front()
	{
		assert(Size());
		if (sPop.empty())
		{
			ExChange(sPush, sPop);
		}
		return sPop.top();
	}
	T& Back()
	{
		assert(Size());
		if (sPush.empty())
		{
			ExChange(sPop, sPush);
		}
		return sPush.top();
	}
	bool Empty()
	{
		return Size()==0;
	}
	size_t Size()
	{
		return sPush.size() + sPop.size();
	}
	
private:
	//这里是将所有元素都导入第二个栈中后在弹出第二个栈的栈顶元素
	void ExChange(stack<T>& sout, stack<T>& sin)//将第一个栈中元素导入到第二个栈中
	{
		while (!sout.empty())//若第一个栈不为空
		{
			sin.push(sout.top());//第一个栈中元素依次导入第二个栈中
			sout.pop();//弹出该元素
		}
	
	}
private:
	stack<T> sPush;
	stack<T> sPop;
};


测试代码:

void TestQueue()
{
	Queue<int> q;
	q.Push(1);
	q.Push(2);
	q.Push(3);
	q.Push(4);
	q.Push(5);
	cout <<q.Size() << endl;
	while (!q.Empty())
	{
		cout <<q.Front() << " ";
		q.Pop();
	}
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值