当前位置:   article > 正文

C语言/数据结构——每日一题(设计循环队列)

C语言/数据结构——每日一题(设计循环队列)

一.前言

上一次我们分享了关于队列的基本实现——https://blog.csdn.net/yiqingaa/article/details/139033067?spm=1001.2014.3001.5502

现在我们将使用队列知识来解决问题——设计循环队列https://leetcode.cn/problems/design-circular-queue/submissions/533299335

二.正文

1.1题目描述

1.2题目分析

本题给了我们七个操作需求,需要我们将这些函数功能实现出来。

对于这道题,假如我们是使用数组来实现队列,在这里我们可以事先模拟走一下:

那么我们如何解决这个问题呢。在这里我们我们可以通过多创建一个空间的方式解决这个问题。

(1)定义栈的结构

  1. typedef struct {
  2. int* a;//a是int*类型的数组
  3. int k;//k代表了我们的数组长度
  4. int head;//head会指向我们的头元素(head在这里不是指针,可以当成另类的下标)
  5. int tail;//tail在我们数据的后一个位置(tail在这里不是指针,可以当成另类的下标)
  6. } MyCircularQueue;

假如k是4,数组有1,2,3,4这些数据。那么就有:

 (2)创建我们的队列

  1. MyCircularQueue* myCircularQueueCreate(int k) {
  2. MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
  3. obj->a=(int*)malloc(sizeof(int)*(k+1));
  4. if(obj->a==NULL)
  5. {
  6. perror("malloc fail!");
  7. }
  8. obj->k=k;
  9. obj->head=obj->tail=0;
  10. return obj;
  11. }

我们首先为我们的队列结构体申请了sizeof(MyCircularQueue)字节大小的空间。

然后又为了我们数组申请了sizeof(int)*(k+1)字节大小的空间。

用我们的结构体成员k接受形参k的值。

并让head,tail都初始化为0。

(3)判断队列是否为空

  1. bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
  2. if(obj->head==obj->tail)
  3. return true;
  4. return false;
  5. }

这里我们先实现了判断队列是否为空的函数功能,因为这个函数功能在后面实现数据插入和删除中都需要用到,因此,在这里我们就先实现了。

 (4)判断队列是否数据已满

  1. bool myCircularQueueIsFull(MyCircularQueue* obj) {
  2. if((obj->tail+1)%(obj->k+1)==obj->head)
  3. return true;
  4. return false;
  5. }

 (5)队列数据的插入

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

这里我们先进行了判断,如果队列数据已经满了,就插不了数据了,直接返回false即可。

在这里,我们需要额外注意这行代码:obj->tail=(obj->tail)%(obj->k+1);

相信同学们看到这里已经发现了,我们上述代码中很多都用到了取余%的应用,这是为了让head和tail能正常的循环。

(6) 队列数据的删除

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

这里我们需要知道,如果队列没有数据的时候,我们不能进行数据删除,因为本来队列都没数据了,再删除就会出现内存泄露的问题。

(7) 取出队头的数据

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

 (8)取出队尾的数据

  1. int myCircularQueueRear(MyCircularQueue* obj) {
  2. if(myCircularQueueIsEmpty(obj)==true)
  3. return -1;
  4. return obj->a[(obj->tail-1+obj->k+1)%(obj->k+1)];
  5. }

 (9)销毁我们创建的对列

  1. void myCircularQueueFree(MyCircularQueue* obj) {
  2. free(obj->a);
  3. free(obj);
  4. }

 1.3代码实现

  1. typedef struct {
  2. int* a;
  3. int k;
  4. int head;
  5. int tail;
  6. } MyCircularQueue;
  7. MyCircularQueue* myCircularQueueCreate(int k) {
  8. MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
  9. obj->a=(int*)malloc(sizeof(int)*(k+1));
  10. if(obj->a==NULL)
  11. {
  12. perror("malloc fail!");
  13. }
  14. obj->k=k;
  15. obj->head=obj->tail=0;
  16. return obj;
  17. }
  18. bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
  19. if(obj->head==obj->tail)
  20. return true;
  21. return false;
  22. }
  23. bool myCircularQueueIsFull(MyCircularQueue* obj) {
  24. if((obj->tail+1)%(obj->k+1)==obj->head)
  25. return true;
  26. return false;
  27. }
  28. bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
  29. if(myCircularQueueIsFull(obj)==true)
  30. return false;
  31. obj->a[obj->tail]=value;
  32. obj->tail++;
  33. obj->tail=(obj->tail)%(obj->k+1);
  34. return true;
  35. }
  36. bool myCircularQueueDeQueue(MyCircularQueue* obj) {
  37. if(myCircularQueueIsEmpty(obj)==true)
  38. return false;
  39. obj->head++;
  40. obj->head=(obj->head)%(obj->k+1);
  41. return true;
  42. }
  43. int myCircularQueueFront(MyCircularQueue* obj) {
  44. if(myCircularQueueIsEmpty(obj)==true)
  45. return -1;
  46. return obj->a[obj->head];
  47. }
  48. int myCircularQueueRear(MyCircularQueue* obj) {
  49. if(myCircularQueueIsEmpty(obj)==true)
  50. return -1;
  51. return obj->a[(obj->tail-1+obj->k+1)%(obj->k+1)];
  52. }
  53. void myCircularQueueFree(MyCircularQueue* obj) {
  54. free(obj->a);
  55. free(obj);
  56. }
  57. /**
  58. * Your MyCircularQueue struct will be instantiated and called as such:
  59. * MyCircularQueue* obj = myCircularQueueCreate(k);
  60. * bool param_1 = myCircularQueueEnQueue(obj, value);
  61. * bool param_2 = myCircularQueueDeQueue(obj);
  62. * int param_3 = myCircularQueueFront(obj);
  63. * int param_4 = myCircularQueueRear(obj);
  64. * bool param_5 = myCircularQueueIsEmpty(obj);
  65. * bool param_6 = myCircularQueueIsFull(obj);
  66. * myCircularQueueFree(obj);
  67. */

以上代码就是我们在力扣网上运行的代码。

三.结言

本题的分享就到这了,有兴趣的小伙伴,能不能给个三连,真的求求了。

帅哥美女们,咱们下期再见。

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

闽ICP备14008679号