您的位置:首页 > 其它

使用两个队列实现一个栈

2016-05-24 15:27 423 查看
首先,我们得了解队列和栈的基本原理。
队列是一个“先进先出“的一个结构。队列的定义是在队尾插入,在队头删除,这就要求要用一种在尾部插入容易的,在头部删除容易的结构,你一定会想到单链表,对,库的实现就是用一个链表实现的。
栈,相信大家都不会陌生,函数栈帧等的实现,它是一种”先进后出“的结构。栈的插入删除都是在尾部进行的。
所以要用队列实现一个栈,要解决的问题就是在删除时要删除最后插入的那个元素。
我们先来模拟一下出栈和入栈的情况:
(1)入栈:Q1:1,2,3,4入队列(相当于入栈);
(2)出栈:Q1:1,2,3出队列,Q2:1,2,3入队列;(此时Q1只剩4,正是我们要出栈的元素)
(3)
1>入栈:Q1:5入队列(每次入栈都用Q1入队列实现,而不入队列Q2,这样会提高效率,后面会说到)
2>出栈:判断:如果Q1队列不为空就用(1)(2)步的方法出栈最后一个元素。否则,出栈Q2队列的最后一个元素。
我们首先来搭建这个栈的结构:
#pragma once
#include<iostream>
#include<queue>
#include<string>
#include<assert.h>

using namespace std;

template<class T>
class MYStack
{
public:
MYStack()
:_size(0)
{
}
~MYStack()
{
}
void Push(const T& x);
void Pop();
bool Empty();
size_t Size();
void Print();

private:
queue<T> q1;
queue<T> q2;
size_t _size;
};
一个栈具有的功能我们都实现一下,Psh(),Pop(),Empty(),Size()等等。
在这个结构中数据成员是两个队列的对象,因为我们是用两个队列来实现的,还有一个_size用来记录栈中元素的个数。
下面是函数具体实现:
template<class T>
void MYStack<T>::Push(const T& x)
{
q1.push(x);
++_size;
}

template<class T>
void MYStack<T>::Pop()
{
//assert(_size > 0);
//size_t plen = q1.size();
//while (plen != 1)
//{
//	T tmp = q1.front();
//	q2.push(tmp);
//	q1.pop();
//	--plen;
//}
//q1.pop();
//plen = q2.size();
//while (plen)
//{
//	T tmp = q2.front();
//	q1.push(tmp);
//	q2.pop();
//	--plen;
//}
//--_size;

assert(_size > 0);
size_t plen = q1.size();
if (plen == 0)
{
//if (q2.size() == 0)
//	return;
plen = q2.size();
while (plen != 1)
{
T tmp = q2.front();
q1.push(tmp);
q2.pop();
--plen;
}
q2.pop();
}
else
{
size_t plen = q1.size();
while (plen != 1)
{
T tmp = q1.front();
q2.push(tmp);
q1.pop();
--plen;
}
q1.pop();
}
--_size;
}

template<class T>
bool MYStack<T>::Empty()
{
return _size ? false : true;
}

template<class T>
size_t MYStack<T>::Size()
{
return _size;
}

template<class T>
void MYStack<T>::Print()
{
//size_t plen = q1.size();
//while (plen--)
//{
//	cout << q1.front() << " ";
//	q1.pop();
//}

size_t plen = q2.size();
while (plen--)
{
cout << q2.front() << " ";
q2.pop();
}
plen = q1.size();
while (plen--)
{
cout << q1.front() << " ";
q1.pop();
}
}
注释掉的部分也可以实现,它的原理是不管第(3)步是出栈还是入栈,都把剩下的元素从Q2出栈入栈到Q1,输出的时候只用输出Q1中的元素。但是它的效率较低。如果有这种情况:1,2,3.....100000入栈,然后1,2,3......100000出栈,这会导致Q1和Q2频繁的出栈和入栈,效率非常之低。
优化方法就是没有注释部分。它的实现就是入栈都是Q1入队列,出栈后不把Q2的元素移到Q1,这样的话效率就会提高,只是在输出的时候要先输出Q2里的元素,再输出Q1里的元素。因为Q1里的元素总是栈顶的元素。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: