两个栈形成一个队列
解题思路:
- 队列是先进先出,有队头和队尾,因此用第一个栈的栈顶表示队头,第二个表示队尾。
- 队列插入的时候是从尾巴插入,因此代表尾部的栈可以定义成一个插入栈也是队尾栈。
- 队列输出遵守先进先出原则,输出的元素是队头,因此代表头部的栈可以定义一个输出栈也叫队头栈。
- 为避免队列顺序错乱,因此两个栈在做插入或者输出时应该保持另一个栈为空
图解:
如上图:当要插入时所有元素放入第一个栈栈顶为队尾插入即插入队列尾部,取出队头的时候将第一个栈所有元素分别放入第二个栈中栈顶就为队头取出栈顶就为队头,两个栈相互转换分别执行自己的功能就实现了先进先出和从尾部输入的功能。
如上图:当第二个栈不为空的时候插入队列变成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;
}
输入结果
上面结果显示代码正确