使用两个栈实现队列
1. 如何使用两个栈实现队列?
因为栈的顺序是后进先出,队列是先进先出。通过把一个栈“倒”进第二个栈,可以在第二个栈以原来入栈的顺序出栈,就达到了队列的先进先出效果。
注意关于如何“倒”,也有效率的高低之分。
我使用的方法是(一个栈称StackIn,另一个栈称StackOut):
1.当入队列时,不用判断StackOut有没有元素,只要没达到队列的上限,就直接压入StackIn。
2.当出队列时,如果StackOut不为空,直接弹出StackOut的栈顶元素;如果StackOut是空的,那么让StackIn的元素先倒进StackOut,再从StackOut弹出栈顶元素。
这种方法时间复杂度是相对其他几种方法比较低的。关于另外几种如何“倒”的方法,更详细的介绍,可以看另一篇博文:http://www.cnblogs.com/wanghui9072229/archive/2011/11/22/2259391.html
2. 使用两个栈实现队列的实现(C++代码)
//SequeStack.h
#pragma once
#include <assert.h>
template<typename ElemType>
class SequeStack
{
public:
SequeStack(unsigned int size);
bool Push(ElemType elem);
bool Pop(ElemType* retElem);
bool Empty() const;
bool Visit(ElemType* elem, unsigned int pos) const;
bool Full() const;
unsigned int const& GetLength() const;
private:
ElemType* m_array;
unsigned int m_top;
unsigned int m_size;
unsigned int m_length;
};
template<typename ElemType>
unsigned int const& SequeStack<ElemType>::GetLength() const
{
return m_top;
}
template<typename ElemType>
bool SequeStack<ElemType>::Full() const
{
return m_top >= m_size ? true : false;
}
template<typename ElemType>
bool SequeStack<ElemType>::Visit(ElemType* elem, unsigned int pos) const
{
if (pos >= m_size || pos < 0)
{
assert(false && "Error: Visit Pos is out range of array!");
return false;
}
*elem = m_array[pos];
return true;
}
template<typename ElemType>
bool SequeStack<ElemType>::Empty() const
{
return m_top ? false : true;
}
template<typename ElemType>
bool SequeStack<ElemType>::Pop(ElemType* retElem)
{
if (Empty())
{
assert(false && "Error: SequeStack is underflow!");
return false;
}
else
{
*retElem = m_array[--m_top];
return true;
}
}
template<typename ElemType>
bool SequeStack<ElemType>::Push(ElemType pushElem)
{
if (m_top == m_size)
{
assert(false && "Error: SequeStack is overflow!");
return false;
}
else
{
m_array[m_top++] = pushElem;
return true;
}
}
template<typename ElemType>
SequeStack<ElemType>::SequeStack(unsigned int size)
: m_array(new ElemType[size]),m_top(0),m_size(size),m_length(0)
{
memset(m_array,0,sizeof(ElemType)*size);
}
//QueueByTwoStack.h
#pragma once
#include <assert.h>
#include "SequeStack.h"
template<typename ElemType>
class QueueByTwoStack
{
public:
QueueByTwoStack(unsigned int size);
bool DeQueue(ElemType* elem);
bool EnQueue(const ElemType& elem);
bool Empty() const;
bool Visit(ElemType* elem, const unsigned int& pos) const;
unsigned int GetLength() const;
private:
bool StackInToStackOut();
SequeStack<ElemType>* m_stackIn;
SequeStack<ElemType>* m_stackOut;
unsigned int m_size;
};
template<typename ElemType>
unsigned int QueueByTwoStack<ElemType>::GetLength() const
{
return m_stackIn->GetLength() + m_stackOut->GetLength();
}
template<typename ElemType>
bool QueueByTwoStack<ElemType>::StackInToStackOut()
{
if (!m_stackOut->Empty()) // StackOut必须为空才能倒
{
return false;
}
while(!m_stackIn->Empty()) //现在将m_stackIn倒进m_stackOut
{
ElemType tempElem;
m_stackIn->Pop(&tempElem);
m_stackOut->Push(tempElem);
}
return true;
}
template<typename ElemType>
bool QueueByTwoStack<ElemType>::Visit(ElemType* elem, const unsigned int& pos) const
{
if (pos >= m_size)
{
return m_stackOut->Visit(elem, pos - m_size);
}
else
{
return m_stackIn->Visit(elem, pos);
}
}
template<typename ElemType>
bool QueueByTwoStack<ElemType>::Empty() const
{
if (m_stackIn->Empty() && m_stackOut->Empty())
return true;
return false;
}
template<typename ElemType>
bool QueueByTwoStack<ElemType>::EnQueue(const ElemType& elem)
{
if ( m_stackIn->Push(elem) && GetLength() <= m_size )
{
return true;
}
assert(false && "Error: SequeDeQueue is overflow!");
return false;
}
template<typename ElemType>
bool QueueByTwoStack<ElemType>::DeQueue(ElemType* elem)
{
if (Empty())
{
assert(false && "Error: SequeDeQueue is underflow!");
return false;
}
StackInToStackOut(); //尝试倒进stackOut
return m_stackOut->Pop(elem);
}
template<typename ElemType>
QueueByTwoStack<ElemType>::QueueByTwoStack(unsigned int size)
:m_stackIn(new SequeStack<ElemType>(size)),m_stackOut(new SequeStack<ElemType>(size)),m_size(size)
{
}
//Util.h
#pragma once
namespace Util
{
template<typename T>
void PrintMemory(const T& dateStruct, unsigned int size)
{
cout << "PrintMemory: ";
for (int i = 0; i != size; i++)
{
ElemType tempElem;
dateStruct.Visit(&tempElem,i);
printf("%d ",tempElem);
}
printf("\n");
printf("\n");
}
}
#include "Util.h"
#include "QueueByTwoStack.h"
#include <iostream>
using namespace std;
typedef int ElemType;
int main()
{
const int QUEUE_SIZE = 6;
QueueByTwoStack<int> testQueueByTwoStack(QUEUE_SIZE);
cout << "testQueueByTwoStack is " << (testQueueByTwoStack.Empty() ? "Empty." : "Not Empty.") << endl;
Util::PrintMemory(testQueueByTwoStack,QUEUE_SIZE*2);
for (int i = 0; i != 4; i++) //4个元素入队列{1、2、3、4}
{
testQueueByTwoStack.EnQueue(i+1);
cout << "EnQueue:" << i+1 << endl;
cout << "testQueueByTwoStack is " << (testQueueByTwoStack.Empty() ? "Empty." : "Not Empty.") << endl;
Util::PrintMemory(testQueueByTwoStack,QUEUE_SIZE*2);
}
for (int i = 0; i != 2; i++) //2个元素出队列{1、2}
{
ElemType tempElem;
testQueueByTwoStack.DeQueue(&tempElem);
cout << "DeQueue:" << tempElem << endl;
cout << "testQueueByTwoStack is " << (testQueueByTwoStack.Empty() ? "Empty." : "Not Empty.") << endl;
Util::PrintMemory(testQueueByTwoStack,QUEUE_SIZE*2);
}
for (int i = 0; i != 4; i++) //4个元素入队列{5、6、7、8}
{
testQueueByTwoStack.EnQueue(i+5);
cout << "EnQueue:" << i+5 << endl;
cout << "testQueueByTwoStack is " << (testQueueByTwoStack.Empty() ? "Empty." : "Not Empty.") << endl;
Util::PrintMemory(testQueueByTwoStack,QUEUE_SIZE*2);
}
for (int i = 0; i != 6; i++) //6个元素出队列{3、4、5、6、7、8}
{
ElemType tempElem;
testQueueByTwoStack.DeQueue(&tempElem);
cout << "DeQueue:" << tempElem << endl;
cout << "testQueueByTwoStack is " << (testQueueByTwoStack.Empty() ? "Empty." : "Not Empty.") << endl;
Util::PrintMemory(testQueueByTwoStack,QUEUE_SIZE*2);
}
return 0;
}
3. 程序运行结果
testQueueByTwoStack is Empty.
PrintMemory: 0 0 0 0 0 0 0 0 0 0 0 0EnQueue:1
testQueueByTwoStack is Not Empty.
PrintMemory: 1 0 0 0 0 0 0 0 0 0 0 0EnQueue:2
testQueueByTwoStack is Not Empty.
PrintMemory: 1 2 0 0 0 0 0 0 0 0 0 0EnQueue:3
testQueueByTwoStack is Not Empty.
PrintMemory: 1 2 3 0 0 0 0 0 0 0 0 0EnQueue:4
testQueueByTwoStack is Not Empty.
PrintMemory: 1 2 3 4 0 0 0 0 0 0 0 0DeQueue:1
testQueueByTwoStack is Not Empty.
PrintMemory: 1 2 3 4 0 0 4 3 2 1 0 0DeQueue:2
testQueueByTwoStack is Not Empty.
PrintMemory: 1 2 3 4 0 0 4 3 2 1 0 0EnQueue:5
testQueueByTwoStack is Not Empty.
PrintMemory: 5 2 3 4 0 0 4 3 2 1 0 0EnQueue:6
testQueueByTwoStack is Not Empty.
PrintMemory: 5 6 3 4 0 0 4 3 2 1 0 0EnQueue:7
testQueueByTwoStack is Not Empty.
PrintMemory: 5 6 7 4 0 0 4 3 2 1 0 0EnQueue:8
testQueueByTwoStack is Not Empty.
PrintMemory: 5 6 7 8 0 0 4 3 2 1 0 0DeQueue:3
testQueueByTwoStack is Not Empty.
PrintMemory: 5 6 7 8 0 0 4 3 2 1 0 0DeQueue:4
testQueueByTwoStack is Not Empty.
PrintMemory: 5 6 7 8 0 0 4 3 2 1 0 0DeQueue:5
testQueueByTwoStack is Not Empty.
PrintMemory: 5 6 7 8 0 0 8 7 6 5 0 0DeQueue:6
testQueueByTwoStack is Not Empty.
PrintMemory: 5 6 7 8 0 0 8 7 6 5 0 0DeQueue:7
testQueueByTwoStack is Not Empty.
PrintMemory: 5 6 7 8 0 0 8 7 6 5 0 0DeQueue:8
testQueueByTwoStack is Empty.
PrintMemory: 5 6 7 8 0 0 8 7 6 5 0 0