3.4.3 循环队列之动态存储空间 (3 )

来源:互联网 发布:青岛知行国际留学 编辑:程序博客网 时间:2024/06/07 19:43

 /* 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;

 

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

 void EnQueue(SqQueue2 *Q,QElemType e)
 { /* 插入元素e为Q的新的队尾元素 */
   int i;
   if(((*Q).rear+1)%(*Q).queuesize==(*Q).front)
   { /* 队列满,增加存储单元 */
     (*Q).base=(QElemType *)realloc((*Q).base,((*Q).queuesize+QUEUE_INCREMENT)*sizeof(QElemType));
     if(!(*Q).base) /* 增加单元失败 */
       exit(ERROR);
     if((*Q).front>(*Q).rear) /* 形成循环 */
     {
       for(i=(*Q).queuesize-1;i>=(*Q).front;i--)
         (*Q).base[i+QUEUE_INCREMENT]=(*Q).base[i]; /* 移动高端元素到新的高端 */
       (*Q).front+=QUEUE_INCREMENT; /* 移动队头指针 */
     }
     (*Q).queuesize+=QUEUE_INCREMENT; /* 增加队列长度 */
   }
   (*Q).base[(*Q).rear]=e; /* 将e插入队尾 */
   (*Q).rear=++(*Q).rear%(*Q).queuesize; /* 移动队尾指针 */
 }

     

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

                                                                                

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

 

 /* main3-8.c 循环且可增加存储空间的顺序队列,检验bo3-8.c的主程序 */
 #include"c1.h"
 typedef int QElemType;
 #include"c3-4.h"
 #include"bo3-4.c" /* 基本操作(1),与非循环同 */
 #include"bo3-8.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);
   for(i=1;i<=3;i++)
     DeQueue(&Q,&d);
   printf("由队头删除3个元素,最后删除的元素为%d\n",d);
   printf("现在队列中的元素为: \n");
   QueueTraverse(Q,print);
   j=GetHead(Q,&d);
   if(j)
     printf("队头元素为: %d\n",d);
   else
     printf("无队头元素(空队列)\n");
   for(i=1;i<=5;i++)
     EnQueue(&Q,i);
   printf("依次向队尾插入1~5,现在队列中的元素为: \n");
   QueueTraverse(Q,print);
   ClearQueue(&Q);
   printf("清空队列后, 队列空否?%u(1:空 0:否)\n",QueueEmpty(Q));
   j=GetHead(Q,&d);
   if(j)
     printf("队头元素为: %d\n",d);
   else
     printf("无队头元素(空队列)\n");
   DestroyQueue(&Q);
 }

原创粉丝点击