当前位置:   article > 正文

数据结构——循环队列(数组实现)_数组实现循环队列

数组实现循环队列

一、概念

普通队列若采用数组实现,随着出队入队操作的进行,队头队尾指针的移动,队头指针走到数组0号位置之后,因为队列只能在队尾插入,那么队头前面的空间就无法再次使用,导致假溢出问题。因此提出了循环队列,其思想是队头或队尾指针到达空间最后一个位置后,下一步移动又会重新返回到初始位置,图示如下:

循环队列为空:队头队尾指针都在初始位置。

满循环队列:为了能使用Q.rear=Q.front来区别是队空还是队满,我们常常认为上图情况时为队满,此时rear+1=front。

注:图示只是为了便于对循环队列的理解,真实的队列还是依靠数组或者链表实现的,内存不会发生弯曲形成头尾相连的情况,而是对指针的操作,实现超过最大位置时就自动返回到初始位置形成循环。

实现方法:每次对队头队尾指针进行改变时,都要对最大容量size进行%取余。若有减法操作,还需先加上最大容量size再对size进行取余,防止数组越界

二、结构体定义

  1. //循环队列
  2. typedef int QDataType;
  3. typedef struct {
  4. QDataType* array;
  5. int front;//队头
  6. int rear;//队尾
  7. int size;//容量
  8. } MyCircularQueue;

三、接口实现

  1. bool myCircularQueueIsEmpty(MyCircularQueue* obj);//判空,空返回true,非空返回false
  2. bool myCircularQueueIsFull(MyCircularQueue* obj);//判满,满返回true,非满返回false
  3. MyCircularQueue* myCircularQueueCreate(int k);//初始化队列
  4. bool myCircularQueueEnQueue(MyCircularQueue* obj, int value);//入队
  5. bool myCircularQueueDeQueue(MyCircularQueue* obj);//出队
  6. int myCircularQueueFront(MyCircularQueue* obj);//获取队头元素
  7. int myCircularQueueRear(MyCircularQueue* obj);//获取队尾元素
  8. void myCircularQueueFree(MyCircularQueue* obj);//销毁

1.循环队列初始化

  1. MyCircularQueue* myCircularQueueCreate(int k) {//初始化队列
  2. MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
  3. if (obj == NULL) {
  4. return NULL;
  5. }
  6. obj->array = (QDataType*)malloc(sizeof(QDataType) * (k + 1));//申请k+1一个空间
  7. obj->front = 0;
  8. obj->rear = 0;
  9. obj->size = k + 1;
  10. return obj;
  11. }

2.循环队列入队

  1. bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {//入队
  2. if (myCircularQueueIsFull(obj)) {
  3. return false;
  4. }
  5. obj->array[obj->rear] = value;
  6. obj->rear = (obj->rear + 1) % obj->size;
  7. return true;
  8. }

3.循环队列出队

  1. bool myCircularQueueDeQueue(MyCircularQueue* obj) {//出队
  2. if (myCircularQueueIsEmpty(obj)) {
  3. return false;
  4. }
  5. obj->front = (obj->front + 1) % obj->size;
  6. return true;
  7. }

4.获取队头元素

  1. int myCircularQueueFront(MyCircularQueue* obj) {//获取队头元素
  2. if (myCircularQueueIsEmpty(obj)) {
  3. return -1;
  4. }
  5. return obj->array[obj->front];
  6. }

5.获取队尾元素

  1. int myCircularQueueRear(MyCircularQueue* obj) {//获取队尾元素
  2. if (myCircularQueueIsEmpty(obj)) {
  3. return -1;
  4. }
  5. return obj->array[(obj->rear - 1+obj->size) % obj->size];
  6. }

6.循环队列判空

  1. bool myCircularQueueIsEmpty(MyCircularQueue* obj) {//判空
  2. if (obj->front == obj->rear) {
  3. return true;
  4. }
  5. return false;
  6. }

7.循环队列判满

  1. bool myCircularQueueIsFull(MyCircularQueue* obj) {//判满
  2. if ((obj->rear + 1) % obj->size == obj->front) {
  3. return true;
  4. }
  5. return false;
  6. }

8.循环队列销毁

  1. void myCircularQueueFree(MyCircularQueue* obj) {//销毁
  2. free(obj->array);
  3. free(obj);
  4. }

四、接口测试

1.测试函数

  1. void Test_Queue() {
  2. MyCircularQueue* obj = myCircularQueueCreate(3);
  3. myCircularQueueEnQueue(obj, 1);
  4. myCircularQueueEnQueue(obj, 2);
  5. myCircularQueueEnQueue(obj, 3);
  6. myCircularQueueEnQueue(obj, 4);//队满
  7. printf("front=%d\n", myCircularQueueFront(obj));//获取队头1
  8. printf("rear=%d\n", myCircularQueueRear(obj));//获取队尾3
  9. myCircularQueueDeQueue(obj);//出队1
  10. printf("front=%d\n", myCircularQueueFront(obj));//获取队头2
  11. myCircularQueueFree(obj);//销毁
  12. }

2.测试结果

五、完整代码

  1. #include<stdio.h>
  2. #include<malloc.h>
  3. #include<stdbool.h>
  4. //循环队列
  5. typedef int QDataType;
  6. typedef struct {
  7. QDataType* array;
  8. int front;//队头
  9. int rear;//队尾
  10. int size;//容量
  11. } MyCircularQueue;
  12. bool myCircularQueueIsEmpty(MyCircularQueue* obj);//判空,空返回true,非空返回false
  13. bool myCircularQueueIsFull(MyCircularQueue* obj);//判满,满返回true,非满返回false
  14. MyCircularQueue* myCircularQueueCreate(int k) {//初始化队列
  15. MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
  16. if (obj == NULL) {
  17. return NULL;
  18. }
  19. obj->array = (QDataType*)malloc(sizeof(QDataType) * (k + 1));//申请k+1一个空间
  20. obj->front = 0;
  21. obj->rear = 0;
  22. obj->size = k + 1;
  23. return obj;
  24. }
  25. bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {//入队
  26. if (myCircularQueueIsFull(obj)) {
  27. return false;
  28. }
  29. obj->array[obj->rear] = value;
  30. obj->rear = (obj->rear + 1) % obj->size;
  31. return true;
  32. }
  33. bool myCircularQueueDeQueue(MyCircularQueue* obj) {//出队
  34. if (myCircularQueueIsEmpty(obj)) {
  35. return false;
  36. }
  37. obj->front = (obj->front + 1) % obj->size;
  38. return true;
  39. }
  40. int myCircularQueueFront(MyCircularQueue* obj) {//获取队头元素
  41. if (myCircularQueueIsEmpty(obj)) {
  42. return -1;
  43. }
  44. return obj->array[obj->front];
  45. }
  46. int myCircularQueueRear(MyCircularQueue* obj) {//获取队尾元素
  47. if (myCircularQueueIsEmpty(obj)) {
  48. return -1;
  49. }
  50. return obj->array[(obj->rear - 1+obj->size) % obj->size];
  51. }
  52. bool myCircularQueueIsEmpty(MyCircularQueue* obj) {//判空
  53. if (obj->front == obj->rear) {
  54. return true;
  55. }
  56. return false;
  57. }
  58. bool myCircularQueueIsFull(MyCircularQueue* obj) {//判满
  59. if ((obj->rear + 1) % obj->size == obj->front) {
  60. return true;
  61. }
  62. return false;
  63. }
  64. void myCircularQueueFree(MyCircularQueue* obj) {//销毁
  65. free(obj->array);
  66. free(obj);
  67. }
  68. void Test_Queue() {
  69. MyCircularQueue* obj = myCircularQueueCreate(3);
  70. myCircularQueueEnQueue(obj, 1);
  71. myCircularQueueEnQueue(obj, 2);
  72. myCircularQueueEnQueue(obj, 3);
  73. myCircularQueueEnQueue(obj, 4);//队满
  74. printf("front=%d\n", myCircularQueueFront(obj));//获取队头1
  75. printf("rear=%d\n", myCircularQueueRear(obj));//获取队尾3
  76. myCircularQueueDeQueue(obj);//出队1
  77. printf("front=%d\n", myCircularQueueFront(obj));//获取队头2
  78. myCircularQueueFree(obj);//销毁
  79. }
  80. int main() {
  81. Test_Queue();
  82. return 0;
  83. }

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

闽ICP备14008679号