一 、
队列的顺序存储结构
与栈类似,队列需要一个指向分配内存的指针。
#include<iostream>
#include<cstdlib>
#define MAXQSIZE 100
typedef struct
{
int *base;//初始化的动态分配存储空间
int front;//头指针,若队列不空则指向队列头元素
int rear;//尾指针,若队列不空指向队尾元素的下一位置
}SqQueue;
建立队列
int InitQueue(SqQueue &Q)
{
Q.base=(int*)malloc(MAXQSIZE*sizeof(int));
if(!Q.base)
exit(-2);
Q.rear=Q.front=0;
return 1;
}
从队尾插入元素
int EnQueue(SqQueue &Q,int e)
{
if((Q.rear+1)%MAXQSIZE==Q.front)//队列满了
return 0;
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXQSIZE;
return 1;
}
这里为什么要对队列的容量进行取余呢?
是因为队列中的元素除了从队尾出队列 也可以从队头出队列,从队头出队列的话会有Q.front++,这是Q.front-1的那块内存会空出来,如果此时Q.rear已经等于MAXQSIZE了,这时候队列看似满了 但实际上没有满 因为空了一个内存,为了避免这种情况,我们采用循环队列来解决这个问题。
出队列
若队列不空则删除队头元素,用e返回其值。
int DeQueue(SqQueue &Q,int &e)
{
if((Q.rear+1)%MAXQSIZE==Q.front)
return 0;
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXQSIZE;
}
求队列中元素的个数
int QueueLength(SqQueue &Q)
{
return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
}
因为使循环队列,所以Q.front可能大于Q.rear直接用Q.rear-Q.front会出现负值。
1.当Q.rear>Q.front(假设前者=5后者等于2)
队列中元素个数为 :(5-2+10)%10=3;
2.当Q.rear<Q.front(假设前者=2后者等于5)
队列中元素个数为:(2-5+10)%10=7;
从上述分析可见,循环队列必须为其设定一个最大队列长度,若用户无法预见队列的最大长度,则宜采用链队列。
二、队列的链式存取
链式存取结构
#include<iostream>
#include<cstdlib>
using namespace std;
typedef Qnode
{
int data;
struct Qnode *next;
}Qnode,*Queueptr;
typedef struct
{
Queueptr front;//队头指针
Queueptr rear;//队尾指针
}LinkQueue;
构造一个空队列
int InitQnode(LinkQueue &Q)
{
Q.rear=Q.front=(int*)malloc(sizeof(Qnode));
if(!Q.front)
exit(-2);
Q.front->next=NULL;
return 1;
}
判断队列空与否
bool QueueEmpty(LinkQueue &Q)
{
return (Q.rear==Q.front)?true:false;
}
队尾增加一个元素
int EnQueue(LinkQueue &Q,int e)
{
Queueptr p;
p=(Queueptr)malloc(sizeof(Qnode));
if(!p)
exit(-2);
p->data=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
return 1;
}
队头删除一个元素并返回其值
int DeQueue(LinkQueue &Q,int &e)
{
if(Q.rear==Q.front)
return 0;
Queueptr p;
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(Q.rear==p)
Q.rear==Q.front;
return 1;
}
销毁队列
int DeQueue(LinkQueue &Q)
{
while(Q.front)
{
Q.rear=Q.front->next;
free(Q.front);
Q.front=Q.rear;
}
return 1;
}