队列简称队,它也是一种运算受限的线性表,其限制是仅允许在表的一端进行插入,而在表的另一端进行删除。我们把进行插入的一端称为队尾,进行删除的一端称为队首。我们又把队列称为先进先出表。
一,队列
的顺序存储:
struct QueueSq{
ElemType *queue;
int front,rear,len;
int MaxSize;
};
初始化队列
void InitQueue(struct QueueSq* Q, int ms)
{
if(ms<=0){printf("ms is not valid!\n");exit(1);}
Q->MaxSize=ms;
Q->queue=malloc(ms*sizeof(ElemType));
if(!Q->queue){
printf("malloc failed\n");
exit(1);
}
Q->front=Q->rear=0;
}
向队列插入元素
void EnQueue(struct QueueSq* Q,ElemType x)
{
if((Q->rear+1)%Q->MaxSize==Q->front) againMalloc(Q);
Q->rear=(Q->rear+1)%Q->MaxSize;
Q->queue[Q->rear]=x;
}
void againMalloc(struct QueueSq* Q)
{
ElemType *p;
p=realloc(Q->queue,2*Q->MaxSize* sizeof(ElemType));
if(!p){
printf("realloc failed!\n");
exit(1);
}
Q->queue=p;
//把原队列的尾部内容后移MaxSize个位置,因为队列可能已经循环使用了,如下图,因为要rear放在新建的空间中使用,所以必须把原来的要素复制到新空间中(红色表示使用的空间,蓝色表示没有使用的空间).
if(Q->rear!=Q->MaxSize-1{
int i;
for(i=0;i<=Q->rear;i++)Q->queue[i+Q->MaxSize]=Q->queue[i];
}
Q->MaxSize=2*Q->MaxSize;
}
从队列中删除元素并返回
ElemType OutQueue(struct QueueSq* Q)
{
if(Q->front==Q->rear){
printf("the queue is empty!\n");
exit(1);
}
Q->front=(Q->front+1)%Q->MaxSize;
return Q->queue[Q->front];
}
读取队首元素,不改变队列的状态
ElemType Peek(struct QueueSq* Q)
{
if(Q->front==Q->rear){
printf("queue is empyt!\n");
exit(1);
}
return Q->queue(Q->front+1)%Q->MaxSize];
}
检查一个队列是否为空,若是则返回1,否则返回0
int EmptyQueue(struct QueueSq* Q)
{
if(Q->front==Q->rear) return 1; else return 0;
}
清空队列
void ClearQueue(struct QueueSq* Q)
if
(Q->queue!=NULL){
free(Q->queue);
Q->queue=0;
Q->front=Q->rear=0;
Q->MaxSize=0;
}
}
二、队列的链接存储
struct QueueLk{
struct sNode* front;
struct sNode* rear;
};
struct sNode{
ElemType data;
struct sNode* next;
};
初始化链队
void InitQueue(struct QueueLk* HQ)
{
HQ->front=HQ->rear=NULL;
}
向链队中插入一个元素
void EnQueue(struct QueueLk* HQ,ElemType x)
{
struct sNode* newp;
newp=malloc(sizeof(struct sNode));
if(newp==NULL){
printf("malloc failed!\n");
exit(1);
}
newp->data=x;
newp->next=NULL:
if(HQ->rear==NULL)
HQ->front=HQ->rear=newp;
else
HQ->rear=HQ->rear->next=newp;
}
从队列中删除一个元素
ElemType OutQueue(struct QueueLk* HQ)
{
struct sNode* p;
ElemType temp;
if(HQ->front==NULL){
printf("queue is empty!\n");
exit(1);
}
temp=HQ->front->data;
p=HQ->front;
HQ->front=p->next;
if(HQ->front==NULL) HQ->rear=NULL;
free(p);
return temp;
}
读取队首元素
ElemType PeekQueue(struct QueueLk* HQ)
{
if(HQ->front==NULL)
{
printf("queue is empty!\n");
exit(1);
}
return HQ->front->data;
}
检查链队是否为空
int EmptyQueue(struct QueuLk* HQ)
{
if(HQ->front==NULL)return 1;else return 0;
}
清空链队
void ClearQueue(struct QueueLk* HQ)
{
struct sNode* p=HQ->front;
while(p!=NULL){
HQ->front=HQ->front->next;
free(p);
p=HQ->front;
}
HQ->rear=NULL;
}
注:队列常用于一下两个方面:1,解决主机与外部设备之间速度不匹配的问题。2,解决由多用户引起的资源竞争问题。