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


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


要使队列具有栈的特性,需要有一个队列来辅助另外一个队列来进行入栈和出栈的操作。


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


给定两个队列:q1,q2,入栈和出栈操作如下:


始终保持所有元素都在一个栈里面

    入栈:如果q1不为空,则给q1入队,如果q1为空q2不为空,则给q2入队,如果q1和q2都为空,则默认给q1入队,一定要始终保证所有的元素都在一个队里面。

    出栈:将不为空的栈里面的元素,除了栈底的那个元素之外,全部出栈并进入另外一个队列,此时再将这个队列里剩下的那个元素进行出队列即可。

给出如下图示:

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

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

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

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

入栈出栈的步骤如上

代码如下:

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

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

	~StackByQueue()
	{}

	void Push(const T& x)
	{
		if (Empty())  //都为空则,则入到q1中
		{
			_q1.push(x);
		}
		else if (!_q1.empty())
		{
			_q1.push(x);
		}
		else
		{
			_q2.push(x);
		}
	}

	void Pop()
	{
		if (Empty())  //都为空
			return;

		if (!_q1.empty())  //q1不为空 q2为空
		{
			while (_q1.size() > 1)
			{
				T tmp = _q1.front();
				_q1.pop();
				_q2.push(tmp);
			}
			_q1.pop();
		}
		else  //q2不为空 q1为空
		{
			while (_q2.size() > 1)
			{
				T tmp = _q2.front();
				_q2.pop();
				_q1.push(tmp);
			}
			_q2.pop();
		}
	}

	T& Top()
	{
		if (Empty())
		{
			exit(1);  //异常退出
		}

		if (!_q1.empty())
		{
			return _q1.back();
		}

		if (!_q2.empty())
		{
			return _q2.back();
		}

	}

	bool Empty()
	{
		return (_q1.empty() && _q2.empty());
	}

	size_t Size()
	{
		return _q1.size() + _q2.size();
	}

private:
	queue<T> _q1;
	queue<T> _q2;
};

void Test1()
{
	StackByQueue<int> s1;
	s1.Push(1);
	s1.Push(2);
	s1.Push(3);
	s1.Push(4);
	s1.Push(5);

	s1.Pop();
	cout << s1.Size() << endl;
	cout << s1.Top() << endl;
}

void Test2()
{
	StackByQueue<string> s1;
	s1.Push("一");
	s1.Push("二");
	s1.Push("三");
	s1.Push("四");
	s1.Push("五");
	
	StackByQueue<string> s2(s1);

}