当前位置:   article > 正文

循环队列的实现

循环队列的实现

 该题目来自力扣,具体要求如下:

 循环队列的实现:

1、构造一个循环队列。

构造循环的队列有两种方式,用顺寻表或者链表实现都可以,两者优势互补,这里重点讲解用顺序表实现。

按照题目要求,该循环队列的长度为K,还有头和尾。所以该队列的结构体中应该有这四种类型。

  1. typedef struct {
  2. int* a;
  3. int front;
  4. int tail;
  5. int k;
  6. } MyCircularQueue;
  7. MyCircularQueue* myCircularQueueCreate(int k) {
  8. MyCircularQueue* q=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
  9. q->a=(int*)malloc(sizeof(int)*(k+1));
  10. q->front=q->tail=0;
  11. q->k=k;
  12. return q;
  13. }

2、向循环队列插入一个元素。如果成功插入则返回真。

当队列容量满的时候,就不能插入,返回false,但是如何判断队列为满呢?假设按照要求开辟K个空间,那么当队列的头与尾重合时,队列的状态要么为空,要么为满,所以需要额外开辟出一个空间。

当开辟的空间为K个时:front等于tail,队列为空。

 当队列满时:front依旧等于tail。

 当额外开辟一个空间时:front等于tail,此时队列为空。

 当队列为满时,front和tail的关系为 (tail+1)%(K+1)。

 所以具体代码为:

  1. bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
  2. //满了,不能在插了
  3. if(myCircularQueueIsFull(obj))
  4. {
  5. return false;
  6. }
  7. obj->a[obj->tail++]=value;
  8. obj->tail %=(obj->k+1);
  9. return true;
  10. }

3、从循环队列中删除一个元素。如果成功删除则返回真。

当队列为空时,无法删除,所以需要返回false。

假设该队列的情况为图所示:当队列的头走到开辟空间的尾时,继续删除队列的头元素,那么需要队列的头转向空间的头,所以在删除时,需要将front%=(k+1),或者直接判断也可以。

 

 

  1. bool myCircularQueueDeQueue(MyCircularQueue* obj) {
  2. if(myCircularQueueIsEmpty(obj)) //空了,不能再删了
  3. {
  4. return false;
  5. }
  6. obj->front++;
  7. obj->front %=(obj->k+1);
  8. return true;
  9. }

4、返回队列的头元素,如果队列为空,则返回-1;

直接返回即可,没有特殊的情况。

  1. int myCircularQueueFront(MyCircularQueue* obj) {
  2. if(myCircularQueueIsEmpty(obj))
  3. {
  4. return -1;
  5. }
  6. return obj->a[obj->front];
  7. }

5、返回队列的尾元素,如果队列为空,则返回-1;

如果是tail不在下标为零的位置,那么直接返回的是 tail-1位置的数据,当tail在第一个位置时,队列的最后一个在下标为4的位置,这是在用tail-1,那么会造成非法访问。

 这种情况有两种方法解决,一种是用if判断,当tail在下标为0的位置时,直接返回下标为4的元素,另一种是用数学公式 直接用(tail+K)%(K+1),无论tail在什么位置,都可以正常的返回。

  1. int myCircularQueueRear(MyCircularQueue* obj) {
  2. if(myCircularQueueIsEmpty(obj))
  3. {
  4. return -1;
  5. }
  6. /*if(obj->tail==0) //下标为0 特殊情况
  7. return obj->a[obj->k];
  8. else
  9. return obj->a[obj->tail-1]; */
  10. int i=(obj->tail+obj->k)%(obj->k+1);
  11. return obj->a[i];
  12. }

附:全部的代码

  1. typedef struct {
  2. int* a;
  3. int front;
  4. int tail;
  5. int k;
  6. } MyCircularQueue;
  7. bool myCircularQueueIsEmpty(MyCircularQueue* obj);
  8. bool myCircularQueueIsFull(MyCircularQueue* obj);
  9. MyCircularQueue* myCircularQueueCreate(int k) {
  10. MyCircularQueue* q=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
  11. q->a=(int*)malloc(sizeof(int)*(k+1));
  12. q->front=q->tail=0;
  13. q->k=k;
  14. return q;
  15. }
  16. bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
  17. //满了,不能在插了
  18. if(myCircularQueueIsFull(obj))
  19. {
  20. return false;
  21. }
  22. obj->a[obj->tail++]=value;
  23. obj->tail %=(obj->k+1);
  24. return true;
  25. }
  26. bool myCircularQueueDeQueue(MyCircularQueue* obj) {
  27. if(myCircularQueueIsEmpty(obj)) //空了,不能再删了
  28. {
  29. return false;
  30. }
  31. obj->front++;
  32. obj->front %=(obj->k+1);
  33. return true;
  34. }
  35. int myCircularQueueFront(MyCircularQueue* obj) {
  36. if(myCircularQueueIsEmpty(obj))
  37. {
  38. return -1;
  39. }
  40. return obj->a[obj->front];
  41. }
  42. int myCircularQueueRear(MyCircularQueue* obj) {
  43. if(myCircularQueueIsEmpty(obj))
  44. {
  45. return -1;
  46. }
  47. /*if(obj->tail==0) //下标为0 特殊情况
  48. return obj->a[obj->k];
  49. else
  50. return obj->a[obj->tail-1]; */
  51. int i=(obj->tail+obj->k)%(obj->k+1);
  52. return obj->a[i];
  53. }
  54. bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
  55. return obj->front==obj->tail;
  56. }
  57. bool myCircularQueueIsFull(MyCircularQueue* obj) {
  58. return (obj->tail+1)%(obj->k+1)==obj->front;
  59. }
  60. void myCircularQueueFree(MyCircularQueue* obj) {
  61. free(obj->a);
  62. obj->k=obj->front=obj->tail=0;
  63. free(obj);
  64. }

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号