两个栈实现队列
解题思路:
- 队列是先进先出,有队头和队尾,因此用第一个栈的栈顶表示队头,第二个表示队尾。
- 队列插入的时候是从尾巴插入,因此代表尾部的栈可以定义成一个插入栈也是队尾栈。
- 队列输出遵守先进先出原则,输出的元素是队头,因此代表头部的栈可以定义一个输出栈也叫队头栈。
- 为避免队列顺序错乱,因此两个栈在做插入或者输出时应该保持另一个栈为空
图解:
如上图:当要插入时所有元素放入第一个栈栈顶为队尾插入即插入队列尾部,取出队头的时候将第一个栈所有元素分别放入第二个栈中栈顶就为队头取出栈顶就为队头,两个栈相互转换分别执行自己的功能就实现了先进先出和从尾部输入的功能。
如上图:当第二个栈不为空的时候插入队列变成6 1 2 3 4 5违背了队列插入在尾部的原则,当第一个栈不为空的时候取出队头元素队列变为6 2 3 4 5 违背了取出队头的原则,因此在做相应操作时,另一个栈应该为空。
代码实现:
创建一个队列类它包含两个栈。并通过两个栈实现他的相关函数。
#pragma once
#include<stack>
using namespace std;
class CQueue
{
/*二个栈实现一个队列*/
//m_push() 用来插入(栈顶为队尾)
//m_printf() 用来输出(栈顶为队头)
private:
stack<int> m_push;
stack<int> m_printf;
public:
//队列的中的相关函数详情查看(STL表)
CQueue();
~CQueue();
bool empty();
void push(const int& val);
int& back();
int& front();
void pop();
int size();
};
相关函数实现:
bool CQueue::empty()
{
if (m_push.empty() && m_printf.empty())//两个队列都为空返回真否则为假
{
return true;
}
else
return false;
}
void CQueue::push(const int& val)
{
if (m_printf.empty())//插入时必须保证输出栈为空。
{
m_push.push(val);//将值放到插入栈中保证插入的是队列的尾部
}
else
{
//将输出栈中的元素放入插入栈保证队列的顺序不破坏
while (!m_printf.empty())
{
m_push.push(m_printf.top());
m_printf.pop();
}
m_push.push(val);
}
}
int& CQueue::back()
{
//返回最后一个数即队尾,插入栈最后一个为队列尾部
if (m_printf.empty())//输出队尾,保证输出栈为空
{
return m_push.top();
}
else
{
//将输出栈中的元素放入插入栈保证队列的顺序不破坏(保证另一个栈为空)
while (!m_printf.empty())
{
m_push.push(m_printf.top());
m_printf.pop();
}
return m_push.top();
}
}
int& CQueue::front()
{
if (m_push.empty())//输出队头,保证插入栈为空
{
return m_printf.top();
}
else
{
////将插入栈中的元素放入输出栈保证队列的顺序不破坏(保证另一个栈为空)
while (!m_push.empty())
{
m_printf.push(m_push.top());
m_push.pop();
}
return m_printf.top();
}
}
void CQueue::pop()//删除队头
{
if (m_push.empty())//删除队头,保证插入栈为空
{
m_printf.pop();//删除输出栈的栈顶即删除队头。
}
else
{
////将插入栈中的元素放入输出栈保证队列的顺序不破坏(保证另一个栈为空)
while (!m_push.empty())
{
m_printf.push(m_push.top());
m_push.pop();
}
m_printf.pop();
}
}
int CQueue::size()
{
return m_push.size() + m_printf.size();//两个栈全部元素相加就为队列大小
}
下面为检验相关函数功能代码:
#include<iostream>
#include"Queue.h"
using namespace std;
int main()
{
CQueue qu;//创建一个两个栈实现的队列
for (int i = 0; i < 10;i++)
{
qu.push(i);//往队列插入元素
}
cout << qu.back() << endl;//输出队尾元素
cout << qu.size() << endl;//输出大小
while (!qu.empty())//判断队是否为空
{
cout << qu.front() << endl;//每次那次队头并输出
qu.pop();//删除队头
}
return 0;
}
输出结果
上面结果显示代码正确
两个队列实现栈
解题思路:
条件:创建两个空队列q1和q2,q1用于存储栈中元素,q2用于在pop()和top()操作时候临时存放q1的元素。
- 出栈pop:先判断队列q1元素数目是否为1,若为一,直接弹出并删除即可;若多于1,则将q1中元素弹出并加入q2直至q1剩余一个元素,将其删除,然后将q2暂存的元素弹出并压入q1即可
- 入栈push:直接将元素加入q1的尾部即可
代码实现:
创建一个栈类,它包含两个队列。并通过两个队列实现他的相关函数。这里写成模板类。
#include<iostream>
#include<queue>
using namespace std;
template <class T>
class QueueToStack
{
private:
queue<T> m_que1;
queue<T> m_que2;
int m_size=0;
public:
~QueueToStack(){}
public:
//判断为空
bool empty()
{
if (m_que1.empty() && m_que2.empty())
{
return true;
}
else
{
return false;
}
}
//删除
void pop()
{
//等存在元素时才可以删除
if (m_size != 0)
{
//第一个队列为空
if (0 == m_que1.size())
{
//除栈底,其他元素给第一个队列
while (m_que2.size() != 1)
{
m_que1.push(m_que2.front());
m_que2.pop();
}
//删除第二个队列的栈底
m_que2.pop();
}
else
{
//除栈底,其他元素给第二个队列
while (m_que1.size() != 1)
{
m_que2.push(m_que1.front());
m_que1.pop();
}
//删除第一个队列的栈底
m_que1.pop();
}
--m_size;
}
}
//返回栈顶
T top()
{//判断是否存在元素
if (m_size != 0)
{
if (0 == m_que1.size())
{
return m_que2.back();
}
else
{
return m_que1.back();
}
}
}
//添加元素
void push(const T& val)
{
//判断那个队列一有元素,添加在该队列的
if (m_que1.empty())
{
m_que2.push(val);
}
else
{
m_que1.push(val);
}
m_size++;
}
//返回栈的大小
int size()
{
return m_size;
}
};
测试程序:
int main()
{
QueueToStack<int> qts;
/*
给栈输入1 2 3
删除栈顶元素
在给栈输入4
*/
qts.push(1);
qts.push(2);
qts.push(3);
qts.pop();
qts.push(4);
while (!qts.empty())
{
cout << qts.top()<<" ";
qts.pop();
}
return 0;
}
结果如下:
小队成员(Wu_0526,qq_49032326,ly1196324806,SamGeren,qq_39124199,Teeeee_)