队列(queue)是一种先进先出(first in first out,FIFO)的线性表,只允许在一端进行插入(入队)操作,在另一端进行删除(出队)操作。允许入队操作的一端称为队尾,允许出队操作的一端称为队头。
一个链队列应有两个分别指向队头和队尾的指针。如果从队列中退出一个元素,必须从单链表的第一个结点中取出队头元素,并删除此结点,而入队的新元素是存放在队尾处的,也就是单链表的最后一个元素的后面,并且吃结点将成为新的队尾。
说明:链队列适合数据元素个数变动比较大的情形,一般不存在溢出的问题,如果程序中要使用多个队列,最好使用链队列,这样将不会出现存储分配的问题,也不必进行数据元素的移动。
LinkQueue.h
#ifndef LINKQUEUE_H_
#define LINKQUEUE_H_
#include <iostream>
using std::cout;
using std::endl;
using std::ostream;
template<typename T>
struct Node
{
T data;
Node<T> *next;
Node();
Node(T item, Node<T> *link=NULL);
};
template <typename T>
Node<T>::Node()
{
next=NULL;
}
template <typename T>
Node<T>::Node(T item, Node<T> *link=NULL)
{
data=item;
next=link;
}
template <typename T>
class LinkQueue
{
protected:
Node<T> *front, *rear;
void Init();
public:
LinkQueue();
virtual ~LinkQueue();
int Length() const;
bool IsEmpty();
void Clear();
void OutQueue(T &e);
void GetHead(T &e) const;
LinkQueue<T> &InQueue(const T &e);
LinkQueue(const LinkQueue<T> ©);
LinkQueue<T> &operator=(const LinkQueue<T> ©);
};
template <typename T>
void LinkQueue<T>::Init()
{
front=new Node<T>;
rear=front;
}
template<typename T>
LinkQueue<T>::LinkQueue()
{
Init();
}
template<typename T>
LinkQueue<T>::~LinkQueue()
{
Clear();
delete front;
}
template <typename T>
int LinkQueue<T>::Length() const
{
Node<T> *tempPtr;
int count=0;
for(tempPtr=front; tempPtr!=NULL; tempPtr=tempPtr->next)
{
++count;
}
return (count-1);
}
template <typename T>
bool LinkQueue<T>::IsEmpty()
{
return front==rear;
}
template <typename T>
void LinkQueue<T>::Clear()
{
Node<T> *tempPtr;
while(front->next!=NULL)
{
tempPtr=front->next;
front->next=tempPtr->next;
delete tempPtr;
}
}
template <typename T>
void LinkQueue<T>::OutQueue(T &e)
{
Node<T> *tempPtr=front;
if(front->next!=NULL)
{
tempPtr=front->next;
e=tempPtr->data;
front->next=tempPtr->next;
delete tempPtr;
}
else
{
cout<<"队列为空,没有数据出队!"<<endl;
}
}
template <typename T>
void LinkQueue<T>::GetHead(T &e) const
{
Node<T> *tempPtr=front;
if(front->next!=NULL)
{
tempPtr=front->next;
e=tempPtr->data;
}
else
{
cout<<"队列为空,没有数据出队!"<<endl;
}
}
template <typename T>
LinkQueue<T> &LinkQueue<T>::InQueue(const T &e)
{
Node<T> *newPtr=new Node<T>;
newPtr->data=e;
rear->next=newPtr;
rear=newPtr;
return *this;
}
template <typename T>
LinkQueue<T>::LinkQueue(const LinkQueue<T> ©)
{
Init();
Node<T> *tempPtr;
T e;
for(tempPtr=copy.front->next; tempPtr!=NULL; tempPtr=tempPtr->next)
{
e=tempPtr->data;
InQueue(e);
}
}
template <typename T>
LinkQueue<T> &LinkQueue<T>::operator=(const LinkQueue<T> ©)
{
if(© != this)
{
Init();
Node<T> *tempPtr;
T e;
for(tempPtr=copy.front->next; tempPtr!=NULL; tempPtr=tempPtr->next)
{
e=tempPtr->data;
InQueue(e);
}
}
return *this;
}
template <typename T>
ostream &operator <<(ostream &os, LinkQueue<T> &LQ)
{
T e;
cout<<"队列为:";
int Len=LQ.Length();
for(int i=0; i<Len; i++)
{
LQ.OutQueue(e);
cout<<e<<" ";
}
cout<<endl;
return os;
}
#endif
LinkQueue.cpp
// LinkQueue.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "LinkQueue.h"
#include<iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
LinkQueue<int> LQ;
LQ.InQueue(1);
LQ.InQueue(2);
LQ.InQueue(3).InQueue(4).InQueue(5);
int e;
LQ.GetHead(e);
LinkQueue<int> copy(LQ);
cout<<"复制的队列1"<<copy;
copy=LQ;
cout<<"复制的队列2"<<copy;
cout<<"头结点"<<e<<endl;
cout<<LQ;
system("pause");
return 0;
}
结果略!