队列是只允许在一端进行插入操作,在另一端进行删除操作的线性表。允许插入的一端称为队尾,允许删除的一端称为对头。
队列的特性:入队的顺序与出队的顺序一致,即先入队者先出队,具有先进先出的特性。
队列的顺序存储
为了存储方法更为有效,让入队出队的时间性能都可以在o(1)时间完成,因此不移动数据元素,而让队头队尾活动。将对头队尾两个位置变量设为front和rear,入队时rear加1,出队时front加1,并且约定,front指向对头元素的前一个位置,rear指向队尾元素位置。
在顺序队列中,随着不断地插入和删除操作,整个队列向数组的高端移动,产生队列的单项移动性。当元素被插入到数组中下标最大的位置之后,数组空间就会用尽,尽管此时数组的低端还有存储空间,就会产生假溢出。解决假溢出的方法为将是将存储数据元素的的数组头尾相接,形成循环,允许队列直接从数组下标最大的位置延续到下标最小的位置(通过取余操作)。队列这种首尾相连的顺序结构称为循环队列。
循环队列的初始化:将front与rear同时指向数组高端,即rear=front=Queuesize-1;
循环队列的销毁:为静态存储分配,无需销毁,析构函数为空。
循环队列入队:将队尾位置rear在循环意义下加1,然后将元素x插入队尾位置。
template<typename T>
void Queue<T>::enqueue(T x){
if((rear+1)%Queuesize==front) throw"上溢";
rear=(rear+1)%Queuesize;
data[rear]=x;
}
循环队列出队:将队头位置front在循环意义下加1,读取并返回对头元素。
template<typename T>
T Queue<T>::outqueue(T x){
if(rear==front) throw"下溢";
front=(front+1)%Queuesize;
return data[front];
}
循环队列取对头元素:读取对头元素
template<typename T>
T Queue<T>::Gethead(T x){
if(rear==front) throw"下溢";
return data[(front+1)%Queuesize];
}
队列的链式存储
队列链式结构体:
struct Node{
int data;
Node *next;
};
链队列的初始化:申请头结点,使队首队尾指针均指向头结点。
Queue::Queue()
{
Node *first;
first=new Node;
first->next=NULL;
front=rear=first;
}
链队列的入队:申请结点,写入数据,插入对尾。
templae<typename T>
void Queue<T>::inqueue(T x){
Node *s;
s=new Node;
s->data=x;
s->next=NULL;
rear->next=s;
rear=s;
}
链队列的出队:暂存队首元素,删除队首节点。
template<typename T>
T Queue::outqueue(){
Node *p;
T x;
if(rear==front) throw"下溢";
p=front->next;
x=p->data;
front->next=p->next;
if(p->next==NULL)
rear=front;
delete p;
return x;
}
链队列的遍历:
template<typename T>
void Queue::bianli()
{
Node *p;
p=front->next;
while(p){
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}