C语言之循环队列判断满与空

何时队列为空?何时为满?

由于入队时尾指针向前追赶头指针,出队时头指针向前追赶尾指针,故队空和队满时头尾指针均相等。因此,我们无法通过front=rear来判断队列“空”还是“满”。

注:先进入的为‘头’,后进入的为‘尾’。

解决此问题的方法至少有三种:

其一是另设一个布尔变量以匹别队列的空和满;

其二是少用一个元素的空间,约定入队前,测试尾指针在循环意义下加1后是否等于头指针,若相等则认为队满(注意:rear所指的单元始终为空);

其三是使用一个计数器记录队列中元素的总数(实际上是队列长度)【最简单方便的方法】

方法一实现:

预设一个标志,tag,初值=0,每当入队成功,tag=1;每当出队成功,tag=0;那么,当front==rear &&  tag 则表示“在入队操作之后front=rear”,显然入队造成的f=r的原因就是满了,故 front==rear &&  tag 表示队列满;同理,front==rear && !tag 表示队列空。 

方法二实现:

   

少用一个元素空间,约定以“队列头指针front在队尾指针rear的下一个位置上”作为队列“满”状态的标志。即:
  队空时: front=rear
  队满时: (rear+1)%maxsize=front

  front指向队首元素,rear指向队尾元素的下一个元素。

  1. /  
  2. //   
  3. // author: kangquan2008@csdn  
  4. //  
  5. /  
  6. #include <stdio.h>  
  7. #include <stdlib.h>  
  8. #include <stdbool.h>  
  9.   
  10. #define QUEUE_SIZE 10  
  11. #define EN_QUEUE 1  
  12. #define DE_QUEUE 2  
  13. #define EXIT     3  
  14.   
  15. typedef int    Item;  
  16. typedef struct QUEUE{  
  17.   
  18.     Item * item;  
  19.     int front;  
  20.     int tear;  
  21.   
  22. }Queue;  
  23.   
  24. int init_queue(Queue * queue)  
  25. {  
  26.     queue->item = malloc(QUEUE_SIZE * sizeof(Item));  
  27.     if(!queue->item)  
  28.     {  
  29.         printf("%s\n","Alloc failed,not memory enough");  
  30.         exit(EXIT_FAILURE);  
  31.     }  
  32.   
  33.     queue->front = queue->tear = 0;  
  34.   
  35.     return 1;  
  36. }  
  37.   
  38. int en_queue(Queue * queue, Item item)  
  39. {  
  40.     if((queue->tear+1) % QUEUE_SIZE == queue->front)  
  41.     {  
  42.         printf("%s\n","The queue is full");  
  43.         return -1;  
  44.     }  
  45.   
  46.     queue->item[queue->tear] = item;  
  47.     queue->tear = (queue->tear + 1) % QUEUE_SIZE;  
  48.   
  49.     return 1;  
  50. }  
  51.   
  52. int de_queue(Queue * queue, Item * item)  
  53. {  
  54.     if(queue->front == queue->tear)  
  55.     {  
  56.         printf("%s\n","The queue is empty");  
  57.         return -1;  
  58.     }  
  59.   
  60.     (*item) = queue->item[queue->front];  
  61.     queue->front = (queue->front + 1) % QUEUE_SIZE;  
  62.   
  63.     return 1;  
  64. }  
  65.   
  66. int destroy_queue(Queue * queue)  
  67. {  free(queue->item);  
  68. }  
  69.   
  70. int main()  
  71. {  
  72.     Queue que;  
  73.     init_queue(&que);  
  74.     int elem;  
  75.     bool flag = true;  
  76.     while(flag)  
  77.     {  
  78.         int choice;  
  79.         printf("1 for en_queue,2 for de_queue,3 for exit\r\nplease input:");  
  80.         scanf("%d",&choice);  
  81.   
  82.         switch((choice))  
  83.         {  
  84.             case EN_QUEUE:  
  85.                 printf("input a num:");  
  86.                 scanf("%d",&elem);  
  87.                 en_queue(&que,elem);  
  88.                 break;  
  89.             case DE_QUEUE:  
  90.                 if(de_queue(&que,&elem) == 1)  
  91.                     printf("front item is:%d\n",elem);  
  92.                 break;  
  93.             case EXIT:  
  94.                 flag = false;  
  95.                 break;  
  96.             default:  
  97.                 printf("error input\n");  
  98.                 break;  
  99.         }  
  100.     }  
  101.   
  102.     destroy_queue(&que);  
  103.     return 0;  
  104. }  

方法三实现、

    

  1. #include <stdio.h>  
  2. #include <assert.h>  
  3. #define QueueSize 100  
  4. typedef char datatype;  
  5. //队列的数据元素  
  6. typedef struct  
  7. {  
  8.      int front;  
  9.      int rear;  
  10.      int count;  //计数器,用来记录元素个数  
  11.      datatype data[QueueSize]; //数据内容  
  12. }cirqueue;  

  1. //置空队  
  2. void InitQueue(cirqueue *q)  
  3. {  
  4.      q->front = q->rear = 0;  
  5.      q->count = 0;  
  6. }  

  1. //判断队满  
  2. int QueueFull(cirqueue *q)  
  3. {  
  4.      return (q->count == QueueSize);  
  5. }  

  1. //判断队空  
  2. int QueueEmpty(cirqueue *q)  
  3. {  
  4.      return (q->count == 0);  
  5. }  

  1. //入队  
  2. void EnQueue(cirqueue *q, datatype x)  
  3. {  
  4.      assert(QueueFull(q) == 0); //q满,终止程序  
  5.   
  6.      q->count++;  
  7.      q->data[q->rear] = x;  
  8.      q->rear = (q->rear + 1)%QueueSize; //循环队列设计,防止内存浪费  

  1. //出队  
  2. datatype DeQueue(cirqueue *q)  
  3. {  
  4.      datatype temp;  
  5.   
  6.      assert(QueueEmpty(q) == 0);//q空,则终止程序,打印错误信息  
  7.   
  8.      temp = q->data[q->front];  
  9.      q->count--;  
  10.      q->front = (q->front + 1)%QueueSize;  
  11.      return temp;  

转载出处:http://blog.csdn.net/lin111000713/article/details/40947267

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值