C++ 使用俩个队列实现一个栈&&使用俩个栈实现一个队列

本文探讨了如何利用两个栈实现队列的功能,以及如何通过两个队列模拟栈的行为。详细介绍了实现过程,并提供了代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

俩个栈实现一个队列

如图所示我们有俩个栈A和B
    我们首先把1,2,3依次入栈之后,如果此时我们需要"出队"我们的做法是把A栈中的元素依次出栈后放入栈B。
然后我们把B的栈顶元素弹出
即可以达到队列的先进先出的特点

把栈A中元素弹出放到栈B中

 

把栈B中的栈顶元素弹出

此时我们再向栈中添加元素时还是向栈A加入元素

只要栈B不为空,我们便一直在栈B中弹出元素

一旦栈B为空我们就把元素从A中向B中"倒",直到A中元素被"倒"完成之后再把栈B的栈顶元素弹出。


 

根据这个思路实现的相关代码:

首先实现一个简单栈

template<typename T>
class Stack
{
private:
	int _top;
	size_t _size;
	T *_data;
	void expand()
	{
		T *nTmp = new T[_size * 2];
		for (int i = 0; i < _top; i++)
			nTmp[i] = _data[i];
		delete[]_data;
		_data = nTmp;
		_size *= 2;
	}
public:
	Stack(size_t size = 10)
	{
		_data = new T[10];
		_top = 0;
		_size = size;
	}
	~Stack() { delete[]_data; }
	void push(const T&val)
	{
		if (full())
			expand();
		_data[_top++] = val;
	}
	Stack(const Stack &obj) = delete;
	void operator=(const Stack &obj) = delete;
	T pop()
	{
		if (empty())
			throw "stack is empty";
		return _data[--_top];
	}
	bool full()const
	{
		return _top == _size;
	}
	bool empty()const
	{
		return _top == 0;
	}
	size_t size()const 
	{
		return _size;
	}
	void show()const 
	{
		for (int i = 0; i < _top; i++)
			cout << _data[i] << " ";
		cout << endl;
	}
};

 用上述栈实现俩个栈模拟队列的类

template<typename T>
class STQ
{
private:
	Stack<T> _stack_push;//需要push时使用的栈
	Stack<T> _stack_pop;//需要pop时使用的栈
public:
	STQ() {}
	~STQ() {}
	STQ(const STQ<T>&src) = delete;
	void operator=(const STQ<T>&src) = delete;
	void push(const T&val) 
	{
		_stack_push.push(val);
	}
	T pop() 
	{
		if (!_stack_pop.empty())
			return _stack_pop.pop();
		else 
		{
			if (_stack_push.empty() && _stack_pop.empty())
				throw STQEMPTY;
			while (!_stack_push.empty())
				_stack_pop.push(_stack_push.pop());
			return _stack_pop.pop();
		}
	}
};

 俩个队列实现一个栈

如图

第一步:我们在队列A中加入三个元素1,2,3

第二步:然后比如我们现在要弹出元素,那么我们的做法是,把队列A的最后一个元素"3"之前的所有元素,出队然后再入队B)如图:

第三步:此时我们把"3"弹出给用户,之后我们要再加入元素需要向不为空的队列入队(此时的队列B)

之后的步骤重复从"第一步"到这里。


根据如上所述的代码

 

简单队列实现

template<typename T>
class Queue
{
private:
	T *_data;
	int _head;
	int _rear;
	size_t _size;
	void expand()
	{
		T *nTmp = new T[_size * 2];
		for (int i = 0; i < _size; i++)
			nTmp[i] = _data[i];
		delete[]_data;
		_data = nTmp;
		_size *= 2;
	}
public:
	Queue(size_t size = 10)
		:_size(size)
		,_head(0)
		,_rear(0)
	{
		_data = new T[size];
	}
	~Queue() { delete[]_data;}
	Queue(const Queue&src) = delete;
	void operator=(const Queue&src) = delete;
	void push(const T&val)
	{
		if (full())
			expand();
		_data[_rear++] = val;
	}
	T pop()
	{
		if (empty())
			throw "queue is empty";
		T res = _data[0];
		for (int i = 1; i < _rear; i++)
			_data[i - 1] = _data[i];
		_rear--;
		return res;
	}
	bool full()const { return _rear == _size; }
	bool empty()const { return _rear == 0; }
	size_t size()const { return _rear - _head; }
	void show()const
	{
		for (int i = 0; i < _rear; i++)
			cout << _data[i] << " ";
		cout << endl;
	}
};

使用俩个队列模拟栈的特性

template<typename T>
class QTS
{
private:
	Queue<T> que1;
	Queue<T> que2;
public:
	QTS() {}
	~QTS() {}
	QTS(const QTS&src) = delete;
	void operator=(const QTS&src) = delete;
	void push(const T &val)
	{
		//直往一个队列中放元素,保
		if (que1.empty())//向另外一个为空或者不为空的队列中放元素
			que2.push(val);
		else
			que1.push(val);
	}
	T pop()
	{
		if (que1.empty() && que2.empty())
			throw QTSEMPTY;
		//首先不为空的队列一直pop到空的队列中直到最后一个为止,把最后一个元素pop给用户
		T last;
		Queue<T> *Full = que1.empty() ? &que2 : &que1;
		Queue<T> *Empty = Full == &que1 ? &que2 : &que1;
		//(除了最后一个元素)把非空的队列中的元素全部入队到另外一个队列
		while (Full->size() != 1)
			Empty->push(Full->pop());
		return Full->pop();
	}
};

下面是所有的代码结合和测试用例

(如果有什么错误的地方,或者可以改进的地方欢迎指出讨论)

#include <iostream>
#include <string.h>
enum error_type{ STQEMPTY, QTSEMPTY };
using namespace std;

template<typename T>
class Stack
{
private:
	int _top;
	size_t _size;
	T *_data;
	void expand()
	{
		T *nTmp = new T[_size * 2];
		for (int i = 0; i < _top; i++)
			nTmp[i] = _data[i];
		delete[]_data;
		_data = nTmp;
		_size *= 2;
	}
public:
	Stack(size_t size = 10)
	{
		_data = new T[10];
		_top = 0;
		_size = size;
	}
	~Stack() { delete[]_data; }
	void push(const T&val)
	{
		if (full())
			expand();
		_data[_top++] = val;
	}
	Stack(const Stack &obj) = delete;
	void operator=(const Stack &obj) = delete;
	T pop()
	{
		if (empty())
			throw "stack is empty";
		return _data[--_top];
	}
	bool full()const
	{
		return _top == _size;
	}
	bool empty()const
	{
		return _top == 0;
	}
	size_t size()const 
	{
		return _size;
	}
	void show()const 
	{
		for (int i = 0; i < _top; i++)
			cout << _data[i] << " ";
		cout << endl;
	}
};
template<typename T>
class Queue
{
private:
	T *_data;
	int _head;
	int _rear;
	size_t _size;
	void expand()
	{
		T *nTmp = new T[_size * 2];
		for (int i = 0; i < _size; i++)
			nTmp[i] = _data[i];
		delete[]_data;
		_data = nTmp;
		_size *= 2;
	}
public:
	Queue(size_t size = 10)
		:_size(size)
		,_head(0)
		,_rear(0)
	{
		_data = new T[size];
	}
	~Queue() { delete[]_data;}
	Queue(const Queue&src) = delete;
	void operator=(const Queue&src) = delete;
	void push(const T&val)
	{
		if (full())
			expand();
		_data[_rear++] = val;
	}
	T pop()
	{
		if (empty())
			throw "queue is empty";
		T res = _data[0];
		for (int i = 1; i < _rear; i++)
			_data[i - 1] = _data[i];
		_rear--;
		return res;
	}
	bool full()const { return _rear == _size; }
	bool empty()const { return _rear == 0; }
	size_t size()const { return _rear - _head; }
	void show()const
	{
		for (int i = 0; i < _rear; i++)
			cout << _data[i] << " ";
		cout << endl;
	}
};
void Test_Stack_Queue()
{
	Stack<int> st;
	for (int i = 0; i < 20; i++)
		st.push(rand() % 100 + 1);
	st.show();
	while (!st.empty())
		cout << st.pop() << " ";
	cout << endl;
	cout << "+++++++++++++++++++++++++++++" << endl;
	Queue<int> que;
	for (int i = 0; i < 20; i++)
		que.push(rand() % 100 + 1);
	que.show();
	while (!que.empty())
		cout << que.pop() << " ";
	cout << endl;
}

template<typename T>
class STQ
{
private:
	Stack<T> _stack_push;//需要push时使用的栈
	Stack<T> _stack_pop;//需要pop时使用的栈
	/*void expand()
	{

	}*/
public:
	STQ() {}
	~STQ() {}
	STQ(const STQ<T>&src) = delete;
	void operator=(const STQ<T>&src) = delete;
	void push(const T&val) 
	{
		_stack_push.push(val);
	}
	T pop() 
	{
		if (!_stack_pop.empty())
			return _stack_pop.pop();
		else 
		{
			if (_stack_push.empty() && _stack_pop.empty())
				throw STQEMPTY;
			while (!_stack_push.empty())
				_stack_pop.push(_stack_push.pop());
			return _stack_pop.pop();
		}
	}
};
template<typename T>
class QTS
{
private:
	Queue<T> que1;
	Queue<T> que2;
public:
	QTS() {}
	~QTS() {}
	QTS(const QTS&src) = delete;
	void operator=(const QTS&src) = delete;
	void push(const T &val)
	{
		//直往一个队列中放元素,保
		if (que1.empty())//向另外一个为空或者不为空的队列中放元素
			que2.push(val);
		else
			que1.push(val);
	}
	T pop()
	{
		if (que1.empty() && que2.empty())
			throw QTSEMPTY;
		//首先不为空的队列一直pop到空的队列中直到最后一个为止,把最后一个元素pop给用户
		T last;
		Queue<T> *Full = que1.empty() ? &que2 : &que1;
		Queue<T> *Empty = Full == &que1 ? &que2 : &que1;
		//(除了最后一个元素)把非空的队列中的元素全部入队到另外一个队列
		while (Full->size() != 1)
			Empty->push(Full->pop());
		return Full->pop();
	}
};
int main()
{
	//栈模拟队列测试代码
	STQ<int> stq;
	for (int i = 0; i < 20; i++)
	{
		int tmp = rand() % 100 + 1;
		stq.push(tmp);
		cout << tmp << " ";
	}
	cout << endl;
	for (int i = 0; i < 20; i++)
		cout << stq.pop() << " ";
	cout << endl;
	try {
		cout << stq.pop() << endl;
	}
	catch (error_type e)
	{
		if(e == STQEMPTY)
			cout << "the queue is empty\n" << endl;
	}
	
	//队列模拟栈测试代码
	QTS<int> qts;
	for (int i = 0; i < 20; i++)
	{
		int tmp = rand() % 100 + 1;
		qts.push(tmp);
		cout << tmp << " ";
	}
	cout << endl;
	for (int i = 0; i < 20; i++)
		cout << qts.pop() << " ";
	cout << endl;
	try {
		cout << qts.pop() << endl;
	}
	catch (error_type e)
	{
		if (e == QTSEMPTY)
			cout << "the stack is empty\n" << endl;
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值