当前位置:   article > 正文

数组模拟循环队列

数组模拟循环队列

  • 简介

队列(queue)在计算机科学中,是一种先进先出的线性表。

它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。

为充分利用向量空间,克服"假溢出"现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列(Circular Queue)。这种循环队列可以以单链表的方式来在实际编程应用中来实现。

本文采用数组模拟循环队列。

  • 判断循环队列为空或满

首先我们初始化一个长度为5的数组,如下图,我们让front和rear都指向它的首部

在使用循环队列,我们把它想象成一个环形结构,如图

由上图我们可以知道当front=rear时,循环队列为空

队列为满的情况比较复杂,如果我们完全填满队列,会发现满时front=rear,此时满和空的条件重复,不能判断,因此我们留一个位置不用来存储数据,如下图

可以发现,如果从左边圆环判断为满,应该是rear+1=front,但是我们不能忽略这个循环队列本质是由数组实现的,若rear+1,就已经超过数组范围,如何又与front比较呢

因此正确的比较方法应该是 (rear+1)%QueueSize=front

其中QueueSize是循环队列分配数组的长度

  • 实现代码+注释

  1. //622 。 设计循环队列
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include<assert.h>
  5. typedef int ElemType;
  6. typedef struct//循环队列结构
  7. {
  8. ElemType* base;
  9. int front;
  10. int rear;
  11. int capacity;
  12. } MyCircularQueue;
  13. bool myCircularQueueIsEmpty(MyCircularQueue* obj)//判断循环队列是否为空,为空返回true
  14. {
  15. assert(obj);
  16. if (obj->front == obj->rear)
  17. return true;
  18. return false;
  19. }
  20. bool myCircularQueueIsFull(MyCircularQueue* obj)//判断循环队列是否为满,为满返回true
  21. {
  22. assert(obj);
  23. if ((obj->rear + 1) % (obj->capacity) == (obj->front))
  24. return true;
  25. return false;
  26. }
  27. MyCircularQueue* myCircularQueueCreate(int k)//传入循环队列大小,生成需要的循环队列
  28. {
  29. MyCircularQueue* CycleQueue = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
  30. if (!CycleQueue)
  31. {
  32. perror("malloc fail");
  33. exit(0);
  34. }
  35. CycleQueue->base = (ElemType*)malloc(sizeof(ElemType) * (k+1));
  36. if (!CycleQueue->base)
  37. {
  38. perror("malloc fail");
  39. exit(0);
  40. }
  41. CycleQueue->front = 0;
  42. CycleQueue->rear = 0;
  43. CycleQueue->capacity = k+1;
  44. return CycleQueue;
  45. }
  46. bool myCircularQueueEnQueue(MyCircularQueue* obj, int value)//在对尾插入元素
  47. {
  48. assert(obj);
  49. if (myCircularQueueIsFull(obj))//如果队列满
  50. {
  51. return false;
  52. }
  53. obj->base[obj->rear] = value;
  54. obj->rear = (obj->rear + 1) % obj->capacity;//加入元素后队列rear后移
  55. return true;//成功加入队列返回true
  56. }
  57. bool myCircularQueueDeQueue(MyCircularQueue* obj)//出队列
  58. {
  59. assert(obj);
  60. if (myCircularQueueIsEmpty(obj))//若队列为空
  61. {
  62. return false;
  63. }
  64. obj->front = (obj->front + 1) % obj->capacity;//加入元素后队列front后移
  65. return true;//成功出队列返回true
  66. }
  67. int myCircularQueueFront(MyCircularQueue* obj)//返回队头
  68. {
  69. assert(obj);
  70. if (myCircularQueueIsEmpty(obj))//若为空队列
  71. {
  72. return -1;
  73. }
  74. return obj->base[obj->front];//返回队头
  75. }
  76. int myCircularQueueRear(MyCircularQueue* obj)//返回队尾
  77. {
  78. assert(obj);
  79. if (myCircularQueueIsEmpty(obj))//若为空队列
  80. {
  81. return -1;
  82. }
  83. return obj->base[(obj->rear - 1+obj->capacity)%obj->capacity];//返回队尾
  84. }
  85. void myCircularQueueFree(MyCircularQueue* obj)//销毁循环队列
  86. {
  87. assert(obj);
  88. assert(obj->base);
  89. free(obj->base);
  90. obj->base = NULL;
  91. free(obj);
  92. obj = NULL;
  93. }
  94. int main()//测试用例
  95. {
  96. MyCircularQueue* obj = myCircularQueueCreate(3);
  97. myCircularQueueEnQueue(obj, 1);
  98. myCircularQueueEnQueue(obj, 2);
  99. myCircularQueueEnQueue(obj, 3);
  100. //myCircularQueueEnQueue(obj, 4);
  101. while (!myCircularQueueIsEmpty(obj))
  102. {
  103. printf("%d", myCircularQueueFront(obj));
  104. myCircularQueueDeQueue(obj);
  105. }
  106. return 0;
  107. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/756366
推荐阅读
相关标签
  

闽ICP备14008679号