当前位置:   article > 正文

数据结构——循环队列_循环队列的优点

循环队列的优点

目录

概念

循环队列的作用

题目

注意事项

题解

用顺序表的实现

用链表的实现


概念

 基于队列的先进先出的原则,在确定了队列长度的前提下,另队列首尾相接而实现的一种结构。

循环队列的作用

循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/design-circular-queue

查看源图像

题目

设置循环队列

注意事项

单纯把链表的首尾相接就可以吗?

那么我们来想想这样一个问题:空的循环队列是什么样的?

我们规定将头指针放在首元素的位置,尾指针放到尾元素的下一个位置,那空队列就是头指针和尾指针指向同一个位置。

那么,满的循环链表又是什么样的呢?

尾指针放在a8元素的后面,恰好又与空链表的指向完全相同。

那我们怎么解决呢?

难道在结构体放一个变量判断它是否以满吗?不是不可以,但稍微有点“笨重”。

所以我们不妨让队列多添加一个位置,这个位置不放任何元素,仅仅是为了区别空与满:

 

题解

与通常队列相似,循环队列同样也可以用链表与顺序表两种方式实现

用顺序表的实现

  1. typedef int CQDataType;
  2. typedef struct
  3. {
  4. CQDataType* cq;
  5. int head;
  6. int tail;
  7. int size;
  8. } myCircularQueueEnQueue;
  9. bool myCircularQueueEnQueueIsFull(myCircularQueueEnQueue* obj);
  10. bool myCircularQueueEnQueueIsEmpty(myCircularQueueEnQueue* obj);
  11. //构造器,设置队列长度为 k
  12. myCircularQueueEnQueue* myCircularQueueEnQueueCreate(int k)
  13. {
  14. myCircularQueueEnQueue* newCQ = (myCircularQueueEnQueue*)malloc(sizeof(myCircularQueueEnQueue));
  15. assert(newCQ);
  16. CQDataType* newcq = (CQDataType*)malloc(sizeof(CQDataType) * (k + 1));
  17. assert(newcq);
  18. newCQ->size = k;
  19. newCQ->cq = newcq;
  20. newCQ->head = 0;
  21. newCQ->tail = 0;
  22. return newCQ;
  23. }
  24. //向循环队列插入一个元素。如果成功插入则返回真
  25. bool myCircularQueueEnQueueEnQueue(myCircularQueueEnQueue* obj, int value)
  26. {
  27. if (myCircularQueueEnQueueIsFull(obj))
  28. {
  29. return 0;
  30. }
  31. obj->cq[obj->tail] = value;
  32. obj->tail = (obj->tail + 1) % (obj->size + 1);
  33. return 1;
  34. }
  35. //从循环队列中删除一个元素。如果成功删除则返回真
  36. bool myCircularQueueEnQueueDeQueue(myCircularQueueEnQueue* obj)
  37. {
  38. if (myCircularQueueEnQueueIsEmpty(obj))
  39. {
  40. return 0;
  41. }
  42. //obj->head = ((obj->size + 1) + (obj->tail - 1)) % (obj->size + 1);
  43. obj->head = (obj->head + 1) % (obj->size + 1);
  44. return 1;
  45. }
  46. //从队首获取元素。如果队列为空,返回 -1
  47. int myCircularQueueEnQueueFront(myCircularQueueEnQueue* obj)
  48. {
  49. if (obj->head == obj->tail)
  50. {
  51. return -1;
  52. }
  53. else
  54. {
  55. return obj->cq[obj->head];
  56. }
  57. }
  58. // 获取队尾元素。如果队列为空,返回 -1
  59. int myCircularQueueEnQueueRear(myCircularQueueEnQueue* obj)
  60. {
  61. if (obj->head == obj->tail)
  62. {
  63. return -1;
  64. }
  65. else
  66. {
  67. return obj->cq[((obj->size + 1) + (obj->tail - 1)) % (obj->size + 1)];
  68. }
  69. }
  70. //检查循环队列是否为空
  71. bool myCircularQueueEnQueueIsEmpty(myCircularQueueEnQueue* obj)
  72. {
  73. return obj->head == obj->tail;
  74. }
  75. //检查循环队列是否已满
  76. bool myCircularQueueEnQueueIsFull(myCircularQueueEnQueue* obj)
  77. {
  78. return (obj->tail + 1) % (obj->size + 1) == obj->head;
  79. }
  80. //释放
  81. void myCircularQueueEnQueueFree(myCircularQueueEnQueue* obj)
  82. {
  83. free(obj->cq);
  84. free(obj);
  85. }

用链表的实现

  1. typedef int CQDataType;
  2. typedef struct CQListNode
  3. {
  4. struct CQListNode* _next;
  5. CQDataType _data;
  6. }CQNode;
  7. typedef struct
  8. {
  9. CQNode* _head;
  10. CQNode* _tail;
  11. int size;
  12. } MyCircularQueue;
  13. bool myCircularQueueIsFull(MyCircularQueue* obj);
  14. bool myCircularQueueIsEmpty(MyCircularQueue* obj);
  15. MyCircularQueue* myCircularQueueCreate(int k)
  16. {
  17. MyCircularQueue* CQ = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
  18. assert(CQ);
  19. CQ->size = k;
  20. CQNode* head = (CQNode*)malloc(sizeof(CQNode));
  21. assert(head);
  22. CQNode* cur = CQ->_head = CQ->_tail = head;
  23. for (int i = 0; i < k; i++)//加上面共k+1个节点
  24. {
  25. CQNode* cq = (CQNode*)malloc(sizeof(CQNode));
  26. assert(cq);
  27. cur->_next = cq;
  28. cq->_next = NULL;
  29. cur = cur->_next;
  30. }
  31. cur->_next = head;
  32. return CQ;
  33. }
  34. bool myCircularQueueEnQueue(MyCircularQueue* obj, int value)
  35. {
  36. if (!myCircularQueueIsFull(obj))
  37. {
  38. obj->_tail->_data = value;
  39. obj->_tail = obj->_tail->_next;
  40. return 1;
  41. }
  42. else
  43. {
  44. return 0;
  45. }
  46. }
  47. bool myCircularQueueDeQueue(MyCircularQueue* obj)
  48. {
  49. if (!myCircularQueueIsEmpty(obj))
  50. {
  51. obj->_head = obj->_head->_next;
  52. return 1;
  53. }
  54. else
  55. {
  56. return 0;
  57. }
  58. }
  59. int myCircularQueueFront(MyCircularQueue* obj)
  60. {
  61. if (!myCircularQueueIsEmpty(obj))
  62. return obj->_head->_data;
  63. else
  64. return -1;
  65. }
  66. int myCircularQueueRear(MyCircularQueue* obj)
  67. {
  68. if (!myCircularQueueIsEmpty(obj))
  69. {
  70. CQNode* cur = obj->_head;
  71. while (cur->_next != obj->_tail)
  72. {
  73. cur = cur->_next;
  74. }
  75. return cur->_data;
  76. }
  77. else
  78. return -1;
  79. }
  80. bool myCircularQueueIsEmpty(MyCircularQueue* obj)
  81. {
  82. return obj->_head == obj->_tail;
  83. }
  84. bool myCircularQueueIsFull(MyCircularQueue* obj)
  85. {
  86. return obj->_tail->_next == obj->_head;
  87. }
  88. void myCircularQueueFree(MyCircularQueue* obj)
  89. {
  90. /*CQListNode* cur = obj->_head;
  91. while(cur->_next!=cur)*/
  92. CQNode* cur = obj->_head;
  93. CQNode* next = NULL;
  94. for (int i = 0; i < obj->size; i++)
  95. {
  96. next = cur->_next;
  97. free(cur);
  98. cur = next;
  99. }
  100. free(obj);
  101. }

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

闽ICP备14008679号