同学说我更新得太慢了。是啊,隔了好久才更新一次。其实我也想快点的更新,更新得越快同时也说明我掌握知识的速度越快,越多。但是工作不允许啊。每天早出晚归,空闲的实现还要分配一点给外语。不过,以后我会努力的,只要有朋友的支持,我会把我的所学和经验奉献给大家。有点开源的精神吧。呵呵,当然了,我还没有哪个资格。
记得,在学校的时候,不论是在课本上,试卷上,还是老师课堂提问。总会不自觉的把栈和队列联系在一起。这充分的说明了栈和队列存在着相似性,同时又有区别。在数据结构(三)中,提到了栈。它是一个后入先出的容器,那么队列又是什么呢?我想,你一定猜到了,队列是先入先出(FIFO)的容器。你看,栈和队列的异同都放在你的面前了。
线性队列和循环队列,是我们者经常使用到两种队列。在两种队列中,数据项都是在队列尾插入,然后移向队列头,并从队列头删除或获取。
为了有助于记忆,我们仍然举一个实际中的例子来说明。给你半分钟想想,什么例子更形象?呵呵!打印机作业,你觉得这个例子怎么样?打印机大家都用过,也知道
它的速度比计算机慢许多,所以操作系统将其打印任务分派给其打印子系统,打印子系统就会将这些任务插入到一个打印队列中。队列中的第一个任务先打印,最后一个任务最后打印。怎么样够形象吧!
这里以一循环队列为例子。和上一篇文章一样,先创建一个队列的基类,然后再派生出来两个子类,我们用数组和链表来分别实现。
#include "List.h"
#include "Array.h"
template <class T>
class Queue
{
public:
virtual T &Head() const = 0;
virtual void Enqueue(T&) = 0;
virtual T &Dequeue() = 0;
protected:
int nLength;
int nCount;
};
数组实现方法:
template <class T>
class QueueArray:public Queue<T>
{
public:
QueueArray(int nCnt)
{
nCount = 0;
nHead = 0;
nTail = 0;
nLength = nCnt;
pArray = new Array<T>(nCnt);
}
~QueueArray()
{
if(NULL != pArray)
{
delete pArray;
}
}
T &Head() const
{
if(0 == nCount)
{
std::domain_error("Queue is empty");
}
return (*pArray)[nHead];
}
void Enqueue(T &value)
{
if(nCount == nLength)
{
std::domain_error("Queue is full");
}
if(++nTail == nLength)
{
nTail = 0;
}
else
{
--nTail;
}
(*pArray)[nTail] = value;
++nTail;
++nCount;
}
T &Dequeue()
{
if(0 == nCount)
{
std::domain_error("Queue is empty");
}
T tResult = (*pArray)[nHead];
if(nHead == nLength)
{
nHead = 0;
}
else
{
++nHead;
}
--nCount;
return tResult;
}
private:
Array<T> *pArray;
int nHead;
int nTail;
};
链表实现方法:
template <class T>
class QueueList:public Queue<T>
{
public:
QueueList(int nCnt)
{
nCount = 0;
nLength = nCnt;
pList = new LinkedList<T>();
}
~QueueList()
{
if(NULL != pList)
{
delete pList;
}
}
T &Head() const
{
if(0 == nCount)
{
std::domain_error("Queue is empty");
}
return const_cast<T&> (pList->GetHead()->GetDatum());
}
void Enqueue(T &value)
{
if(nLength == pList->GetLength())
{
std::domain_error("Queue is full");
}
pList->Append(value);
++nCount;
}
T &Dequeue()
{
if(0 == nCount)
{
std::domain_error("Queue is empty");
}
T tRuselt = pList->GetHead()->GetDatum();
pList->DelElement(1);
--nCount;
return tRuselt;
}
private:
LinkedList<T> *pList;
};