题目描述:用两个栈实现一个队列


分析:  栈的特性是后进先出,队列的特性是先进先出。


    如果用栈实现队列,入队的时候,应该直接给其中一个栈进行入栈操作,关键就在于怎样出队列,对于队列来说,出队列是在队头操作,也就是需要将先入栈(栈底元素)的元素让其出栈,显然,一个栈是不能实现直接删除栈底元素的,这就需要借助另外一个栈来实现这样的操作。


废话不多说,直接给出最高效的方法:

    

    给定两个栈,s1,s2,其中s1只用来进行出栈操作,出栈时再借助s2,入队出队步骤如下:


    入队:直接给s1进行入栈操作,不用检查s1是否为空;

    出队:若s2不为空,直接对s2进行一次出栈操作,若s2为空,则将s1中的元素全部“倒入”s2,再对s2进行出栈操作;

    用两个栈实现一个队列_一个队列

用两个栈实现一个队列_一个队列_02

用两个栈实现一个队列_两个栈_03

用两个栈实现一个队列_实现_04

按照上述步骤,即可实现队列的基本操作


代码如下:


#pragma once
#include<iostream>
#include<stack>
using namespace std;

template<class T>
class QueueByStack
{
public:
	QueueByStack()
	{}

	~QueueByStack()
	{}

	void Push(const T& x)
	{
		_s1.push(x);  //_s1只负责入栈,不用检查s1是否为空
	}

	void Pop()
	{
		if (Empty())
			return;

		if (_s2.empty())
		{
			while (!_s1.empty())
			{
				T tmp = _s1.top();
				_s2.push(tmp);
				_s1.pop();
			}
			_s2.pop();
		}
		else
		{
			_s2.pop();
		}
	}

	T& Back()  //获取队尾元素
	{
		if (Empty())
		{
			exit(1);  //异常退出
		}
		else
		{
			if (_s1.empty())
			{
				while (!_s2.empty())
				{
					T tmp = _s2.top();
					_s2.pop();
					_s1.push(tmp);
				}
			}
			return _s1.top();
		}
	}

	T& Front()  //获取队头元素
	{
		if (Empty())
		{
			exit(1);
		}
		else
		{
			if (_s2.empty())
			{
				while (!_s1.empty())
				{
					T tmp = _s1.top();
					_s1.pop();
					_s2.push(tmp);
				}
			}
			return _s2.top();
		}
	}

	bool Empty()
	{
		return (_s1.empty() && _s2.empty());
	}

	size_t Size()
	{
		return _s1.size() + _s2.size();
	}

protected:
	void Swap(QueueByStack<T>& q)
	{
		std::swap(_s1, q._s1);
		std::swap(_s2, q._s2);
	}

private:
	stack<T> _s1;
	stack<T> _s2;
};