3.4.3 循环队列--------队列的顺序表示与实现(1)

队列的顺序表示为什么要采用循环方式呢?首先分析非循环顺序队列的表示和实现以及他们存在的问题。

 /* c3-5.h 队列的顺序存储结构(非循环队列,队列头元素在[0]单元) */
 #define QUEUE_INIT_SIZE 10 /* 队列存储空间的初始分配量 */
 #define QUEUE_INCREMENT 2 /* 队列存储空间的分配增量 */
 typedef struct
 {
   QElemType *base; /* 初始化的动态分配存储空间 */
   int rear; /* 尾指针,若队列不空,指向队列尾元素的下一个位置 */
   int queuesize; /* 当前分配的存储容量(以sizeof(QElemType)为单位) */
 }SqQueue1;
                                                                      3.4.3 循环队列--------队列的顺序表示与实现(1)_第1张图片

3.4.3 循环队列--------队列的顺序表示与实现(1)_第2张图片

 

 /* bo3-7.c 顺序非循环队列(存储结构由c3-5.h定义)的基本操作(9个) */
 void InitQueue(SqQueue1 *Q)
 { /* 构造一个空队列Q */
   (*Q).base=(QElemType*)malloc(QUEUE_INIT_SIZE*sizeof(QElemType));
   if(!(*Q).base)
     exit(ERROR); /* 存储分配失败 */
   (*Q).rear=0; /* 空队列,尾指针为0 */
   (*Q).queuesize=QUEUE_INIT_SIZE; /* 初始存储容量 */
 }

                                                                                    3.4.3 循环队列--------队列的顺序表示与实现(1)_第3张图片

 void DestroyQueue(SqQueue1 *Q)
 { /* 销毁队列Q,Q不再存在 */
   free((*Q).base); /* 释放存储空间 */
   (*Q).base=NULL;
   (*Q).rear=(*Q).queuesize=0;
 }

                                                                                  3.4.3 循环队列--------队列的顺序表示与实现(1)_第4张图片

 void ClearQueue(SqQueue1 *Q)
 { /* 将Q清为空队列 */
   (*Q).rear=0;
 }

 Status QueueEmpty(SqQueue1 Q)
 { /* 若队列Q为空队列,则返回TRUE;否则返回FALSE */
   if(Q.rear==0)
     return TRUE;
   else
     return FALSE;
 }

 int QueueLength(SqQueue1 Q)
 { /* 返回Q的元素个数,即队列的长度 */
   return Q.rear;
 }

 Status GetHead(SqQueue1 Q,QElemType *e)
 { /* 若队列不空,则用e返回Q的队头元素,并返回OK;否则返回ERROR */
   if(Q.rear)
   {
     *e=*Q.base;
     return OK;
   }
   else
     return ERROR;
 }

 void EnQueue(SqQueue1 *Q,QElemType e)
 { /* 插入元素e为Q的新的队尾元素 */
   if((*Q).rear==(*Q).queuesize) /* 当前存储空间已满 */
   { /* 增加分配 */
     (*Q).base=(QElemType*)realloc((*Q).base,((*Q).queuesize+QUEUE_INCREMENT)*sizeof(QElemType));
     if(!(*Q).base) /* 分配失败 */
       exit(ERROR);
     (*Q).queuesize+=QUEUE_INCREMENT; /* 增加存储容量 */
   }
   (*Q).base[(*Q).rear++]=e; /* 入队新元素,队尾指针+1 */
 }

                                                                                         3.4.3 循环队列--------队列的顺序表示与实现(1)_第5张图片    

 Status DeQueue(SqQueue1 *Q,QElemType *e)
 { /* 若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR */
   int i;
   if((*Q).rear) /* 队列不空 */
   {
     *e=*(*Q).base;
     for(i=1;i<(*Q).rear;i++)
       (*Q).base[i-1]=(*Q).base[i]; /* 依次前移队列元素 */
     (*Q).rear--; /* 尾指针前移 */
     return OK;
   }
   else
     return ERROR;
 }

                                               3.4.3 循环队列--------队列的顺序表示与实现(1)_第6张图片

 void QueueTraverse(SqQueue1 Q,void(*vi)(QElemType))
 { /* 从队头到队尾依次对队列Q中每个元素调用函数vi() */
   int i;
   for(i=0;i<Q.rear;i++)
     vi(Q.base[i]);
   printf("\n");
 }

 

 

 /* main3-7.c 检验bo3-7.cpp的主程序 */
 #include"c1.h"
 typedef int QElemType;
 #include"c3-5.h"
 #include"bo3-7.c"

 void print(QElemType i)
 {
   printf("%d ",i);
 }

 void main()
 {
   Status j;
   int i,k=5;
   QElemType d;
   SqQueue1 Q;
   InitQueue(&Q);
   printf("初始化队列后,队列空否?%u(1:空 0:否)\n",QueueEmpty(Q));
   for(i=1;i<=k;i++)
     EnQueue(&Q,i); /* 依次入队k个元素 */
   printf("依次入队%d个元素后,队列中的元素为: ",k);
   QueueTraverse(Q,print);
   printf("队列长度为%d,队列空否?%u(1:空 0:否)\n",QueueLength(Q),QueueEmpty(Q));
   DeQueue(&Q,&d);
   printf("出队一个元素,其值是%d\n",d);
   j=GetHead(Q,&d);
   if(j)
     printf("现在队头元素是%d\n",d);
   ClearQueue(&Q);
   printf("清空队列后, 队列空否?%u(1:空 0:否)\n",QueueEmpty(Q));
   DestroyQueue(&Q);
 }

 

3.4.3 循环队列--------队列的顺序表示与实现(1)_第7张图片

 

3.4.3 循环队列--------队列的顺序表示与实现(1)_第8张图片

 /* c3-4.h 队列的顺序存储结构(出队元素时不移动元素,只改变队头元素的位置) */
 #define QUEUE_INIT_SIZE 10 /* 队列存储空间的初始分配量 */
 #define QUEUE_INCREMENT 2 /* 队列存储空间的分配增量 */
 typedef struct
 {
   QElemType *base; /* 初始化的动态分配存储空间 */
   int front; /* 头指针,若队列不空,指向队列头元素 */
   int rear; /* 尾指针,若队列不空,指向队列尾元素的下一个位置 */
   int queuesize; /* 当前分配的存储容量(以sizeof(QElemType)为单位) */
 }SqQueue2;
                                                                            3.4.3 循环队列--------队列的顺序表示与实现(1)_第9张图片       

 

 

3.4.3 循环队列--------队列的顺序表示与实现(1)_第10张图片

 /* bo3-4.cpp 顺序队列(存储结构由c3-4.h定义)的基本操作(5个) */
 void InitQueue(SqQueue2 *Q)
 { /* 构造一个空队列Q */
   (*Q).base=(QElemType *)malloc(QUEUE_INIT_SIZE*sizeof(QElemType));
   if(!(*Q).base) /* 存储分配失败 */
     exit(ERROR);
   (*Q).front=(*Q).rear=0;
   (*Q).queuesize=QUEUE_INIT_SIZE;
 }

                                                                                   3.4.3 循环队列--------队列的顺序表示与实现(1)_第11张图片            

 void DestroyQueue(SqQueue2 *Q)
 { /* 销毁队列Q,Q不再存在 */
   if((*Q).base)
     free((*Q).base);
   (*Q).base=NULL;
   (*Q).front=(*Q).rear=(*Q).queuesize=0;
 }

                                                                                3.4.3 循环队列--------队列的顺序表示与实现(1)_第12张图片

 void ClearQueue(SqQueue2 *Q)
 { /* 将Q清为空队列 */
   (*Q).front=(*Q).rear=0;
 }

 Status QueueEmpty(SqQueue2 Q)
 { /* 若队列Q为空队列,则返回TRUE;否则返回FALSE */
   if(Q.front==Q.rear) /* 队列空的标志 */
     return TRUE;
   else
     return FALSE;
 }

 Status GetHead(SqQueue2 Q,QElemType *e)
 { /* 若队列不空,则用e返回Q的队头元素,并返回OK;否则返回ERROR */
   if(Q.front==Q.rear) /* 队列空 */
     return ERROR;
   *e=Q.base[Q.front];
   return OK;
 }

 

 

 /* bo3-9.cpp 顺序非循环队列(存储结构由c3-4.h定义)的基本操作(4个) */
 int QueueLength(SqQueue2 Q)
 { /* 返回Q的元素个数,即队列的长度 */
   return(Q.rear-Q.front);
 }

 void EnQueue(SqQueue2 *Q,QElemType e)
 { /* 插入元素e为Q的新的队尾元素 */
   if((*Q).rear==(*Q).queuesize)
   { /* 队列满,增加存储单元 */
     (*Q).base=(QElemType *)realloc((*Q).base,((*Q).queuesize+QUEUE_INCREMENT)*sizeof(QElemType));
     if(!(*Q).base) /* 增加单元失败 */
       exit(ERROR);
   }
   (*Q).base[(*Q).rear++]=e;
 }

                                               3.4.3 循环队列--------队列的顺序表示与实现(1)_第13张图片

 Status DeQueue(SqQueue2 *Q,QElemType *e)
 { /* 若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR */
   if((*Q).front==(*Q).rear) /* 队列空 */
     return ERROR;
   *e=(*Q).base[(*Q).front++];
   return OK;
 }

                                             3.4.3 循环队列--------队列的顺序表示与实现(1)_第14张图片

 void QueueTraverse(SqQueue2 Q,void(*vi)(QElemType))
 { /* 从队头到队尾依次对队列Q中每个元素调用函数vi() */
   int i=Q.front;
   while(i!=Q.rear)
     vi(Q.base[i++]);
   printf("\n");
 }


 /* main3-4.c 顺序队列(非循环),检验bo3-4.c和bo3-9.c的主程序 */
 #include"c1.h"
 typedef int QElemType;
 #include"c3-4.h"
 #include"bo3-4.c" /* 基本操作(1) */
 #include"bo3-9.c" /* 基本操作(2) */

 void print(QElemType i)
 {
   printf("%d ",i);
 }

 void main()
 {
   Status j;
   int i,n=11;
   QElemType d;
   SqQueue2 Q;
   InitQueue(&Q);
   printf("初始化队列后,队列空否?%u(1:空 0:否)\n",QueueEmpty(Q));
   printf("队列长度为:%d\n",QueueLength(Q));
   printf("请输入%d个整型队列元素:\n",n);
   for(i=0;i<n;i++)
   {
     scanf("%d",&d);
     EnQueue(&Q,d);
   }
   printf("队列长度为:%d\n",QueueLength(Q));
   printf("现在队列空否?%u(1:空 0:否)\n",QueueEmpty(Q));
   printf("现在队列中的元素为: \n");
   QueueTraverse(Q,print);
   DeQueue(&Q,&d);
   printf("删除队头元素%d\n",d);
   printf("队列中的元素为: \n");
   QueueTraverse(Q,print);
   j=GetHead(Q,&d);
   if(j)
     printf("队头元素为: %d\n",d);
   else
     printf("无队头元素(空队列)\n");
   ClearQueue(&Q);
   printf("清空队列后, 队列空否?%u(1:空 0:否)\n",QueueEmpty(Q));
   j=GetHead(Q,&d);
   if(j)
     printf("队头元素为: %d\n",d);
   else
     printf("无队头元素(空队列)\n");
   DestroyQueue(&Q);
 }

3.4.3 循环队列--------队列的顺序表示与实现(1)_第15张图片

3.4.3 循环队列--------队列的顺序表示与实现(1)_第16张图片

你可能感兴趣的:(3.4.3 循环队列--------队列的顺序表示与实现(1))