队列是一种先进先出的(First in First out)的数据结构,只允许插入的一端为队尾,允许删除的一端为队头。
链队列的存储示意图如下
需要注意的是在链队列中,front指针并不是指向队头的,而是指向一个固定的头结点。换句话说,无论队头如何变化,该链队列存储的初始位置不会发生变化。
整的队列的操作如下
注意红色的表示的指针从生成之后就没被修改过了,也就是说在队头之前还有个BOSS在管理整个队伍。
#ifndef QUEUE_H_
#define QUEUE_H_
using namespace std;
template <class Temp>
struct QueueNode
{
Temp data;
QueueNode<Temp> *next;
QueueNode(QueueNode<Temp> *ptr = NULL){ next = ptr; } //struct构造函数
QueueNode(const Temp &item, QueueNode<Temp> *ptr = NULL) //函数参数表中的形参允许有默认值,但是带默认值的参数需要放后面
{
next = ptr;
data = item;
}
};
template <class Temp>
class Queue
{
public:
Queue();
//构造函数
Queue(Queue<Temp> const &q);
//拷贝构造函数
Queue<Temp>& operator= (Queue<Temp> &q);
//赋值构造函数
~Queue();
//析构函数
void DestoryQueue();
//摧毁队列
void ClearQueue();
//清空队列
bool QueueEnpty();
//若队列为空返回TRUE 否则返回false
int QueueLength();
//返回队列中元素的个数
void EnQueue(Temp elem);
//插入元素elem成为队列的队尾元素
bool Gethead(Temp &elem);
//若队列不空,用e返回队首的元素,并返回TRUE 否则返回ERROR
bool DeQueue(Temp &elem);
//若队列不空,用e返回队首的元素,并返回TRUE 否则返回ERROR
void ShowQueue();
//显示队列中的元素
private:
QueueNode<Temp> *front;
QueueNode<Temp> *rear;
};
template <class Temp>
Queue<Temp>::Queue()
{
//构造函数
front = rear = new QueueNode<Temp>;
if (front==NULL||rear==NULL)
{
exit(1);
}
}
template <class Temp>
Queue<Temp>::Queue(const Queue<Temp> &q)
{
//拷贝构造函数
front = rear = new QueueNode<Temp>;
if (front == NULL || rear == NULL)
{
exit(1);
}
QueueNode<Temp> *p = q.front->next;
while (p!=NULL)
{
EnQueue(p->data);
p = p->next;
}
}
template <class Temp>
Queue<Temp>& Queue<Temp>::operator = (Queue<Temp> &q)
{
//赋值构造函数
DestoryQueue();
front = rear = new QueueNode<Temp>;
if (front == NULL || rear == NULL)
{
exit(1);
}
QueueNode<Temp> *p = q.front->next;
while (p != NULL)
{
EnQueue(p->data);
p = p->next;
}
return *this;
}
template <class Temp>
Queue<Temp>::~Queue()
{
//析构函数
DestoryQueue();
}
template <class Temp>
void Queue<Temp>::DestoryQueue()
{
//摧毁队列
while (front)
{
rear = front->next;
delete front;
front = rear;
}
}
template <class Temp>
void Queue<Temp>::ClearQueue()
{
//清空队列
QueueNode<Temp> *p = front->next;
while (p!=NULL)
{
p->data = 0;
p = p->next;
}
}
template <class Temp>
bool Queue<Temp>::QueueEnpty()
{
//若队列为空返回TRUE 否则返回false
if (front==rear)
{
return true;
}
else
{
return false;
}
}
template <class Temp>
int Queue<Temp>::QueueLength()
{
//返回队列中元素的个数
QueueNode<Temp> *p = front->next;
int num = 0;
while (p != NULL)
{
p = p->next;
num++;
}
return num;
}
template <class Temp>
void Queue<Temp>::EnQueue(Temp elem)
{
//插入元素elem成为队列的队尾元素
QueueNode<Temp> *p = new QueueNode<Temp>;
p->data = elem;
rear->next = p;
rear = rear->next;
}
template <class Temp>
bool Queue<Temp>::Gethead(Temp &elem)
{
//若队列不空,用e返回队首的元素,并返回TRUE 否则返回ERROR
if (QueueEnpty())
{
return false;
}
else
{
QueueNode<Temp> *p = front->next;
elem = p->data;
return true;
}
}
template <class Temp>
bool Queue<Temp>::DeQueue(Temp &elem)
{
//若队列不空,用e返回队首的元素,并返回TRUE 否则返回ERROR
if (QueueEnpty())
{
return false;
}
else
{
QueueNode<Temp> *p = front->next;
elem = p->data;
front->next = p->next;
delete p;
}
}
template <class Temp>
void Queue<Temp>::ShowQueue()
{
//显示队列中的元素
if (QueueEnpty())
{
cerr << "NULL" << endl;
}
else
{
QueueNode<Temp> *p = front->next;
while (p != NULL)
{
cout << p->data<<" ";
p = p->next;
}
cout << endl;
}
}
#endif
和链表相似,依然要注意显示定义深度复制。