• 队列OJ--循环队列


    目录

    题目链接:622. 设计循环队列 - 力扣(LeetCode)​​​​​

    题解:

    ​编辑

    代码实现:

    完整代码:


    题目链接:622. 设计循环队列 - 力扣(LeetCode)​​​​​


    题解:

            循环队列的意思就是,如果将插入的数据删除后,原来的空间可以重复使用。

            我们能想到的就是利用数组或者链表这两种数据结构。

            如果使用数组的话那么数组到尾之后,要将下标置为0。

            如果使用链表的话,那么可能就要用到双向链表,当到达尾部的时候,就要重新回到头。但每次插入新的数据的时候,都要malloc新的节点,无疑增大了工作量,似乎会更复杂一些。

            本题我们就使用数组来实现:数组到尾之后,要将下标置为0,然后开始新一轮的循环。

            这时我们就遇到两个问题了,什么时候为空?什么时候为满?

            为空的情况我们是很容易想到的,此时我们定义两个指针,front(控制出队)和back(控制入队),如果front等于back那我们就认为数据为空。

            那空我们解决了,那什么情况又为满呢?

            当back到达尾部时,下标重置,此时front==back,此时可以为满?这样的话,back==front既是空,又是满,这样两种情况就区分不开了。

            这里有两种方法:1.增加一个size,size==0为空,非为插入数据总数就是满。

                                         2.增加一个控制位。

            这里我们就选择第二种方法来实现,增加一个控制位。这个位置也是存放数据的,循环起来空的是任意位置,如果插入4个数据,我们就开5个数据大小的空间。

            我们让back永远指向数据的下一个位置,back位置就不存数据。

            这样一来,如果back的下一个是front,那就代表数据存满了。

            随之也会出现下面两种情况,右边的这种情况real+1==front就能判断存满了。那左边这个back+1他就不能判断了,还会造成假越界的问题。这时我们就可以让back+1模上一个k

    +1,表达式就可以写成:(back+1)%(k+1)==front。左边back值为4,这时(4+1)%(4+1)==0成立。右边(1+1)%(4+1)==2成立。这样一来问题就解决了。


    代码实现:

    1.结构体成员介绍:

    1. typedef struct {
    2. int*a ;
    3. int front;
    4. int back;
    5. int k;
    6. } MyCircularQueue;

            a为开辟的数组,k为入队数据个数  。

    2.初始化

    1. MyCircularQueue* myCircularQueueCreate(int k) {
    2. MyCircularQueue*obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    3. obj->a = (int*)malloc(sizeof(int)*(k+1));
    4. obj->front = 0;
    5. obj->back = 0;
    6. obj->k = k;
    7. return obj;
    8. }

    3.判空和判满

    1. bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    2. return obj->front == obj->back;
    3. }
    4. bool myCircularQueueIsFull(MyCircularQueue* obj) {
    5. return (obj->back+1)%(obj->k+1) == obj->front;
    6. }

            实现下面接口要用到这两个函数,我们可以将之挪到前面,也可以在上面单独声明。

    4.入队

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

            入队需要注意:首先要判满,然后插入数据,最后还要考虑如果back下标如果到尾,还要将back重置为0,这里我们也可以用到取模的方法,back小于k+1back值不变back=k+1 back=k+1,back重置为0。

    5.出队

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

            出队需要注意:首先要判空,然后删除数据,和back一样也要检出front下标是否到尾。

    6.取队头数据

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

            取队头数据,先要判空,如果为空,根据题目要求要返回-1,否则返回队头数据。

    7.取队尾数据

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

             取队尾数据  ,先要判空,如果为空,根据题目要求要返回-1,否则返回队尾数据。

            如果遇到这种情况:back-1=-1,这就取不到队尾数据了。这时(obj->back-1+obj->k+1)%(obj->k+1)我们可以这样写,加上一个(k+1),就可以解决back为0 的情况了。如果back不为0,那么模上一个(k+1)就能把加上的(k+1)模掉。

    8.free

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

    完整代码:

    1. typedef struct {
    2. int*a ;
    3. int front;
    4. int back;
    5. int k;
    6. } MyCircularQueue;
    7. MyCircularQueue* myCircularQueueCreate(int k) {
    8. MyCircularQueue*obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    9. obj->a = (int*)malloc(sizeof(int)*(k+1));
    10. obj->front = 0;
    11. obj->back = 0;
    12. obj->k = k;
    13. return obj;
    14. }
    15. bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    16. return obj->front == obj->back;
    17. }
    18. bool myCircularQueueIsFull(MyCircularQueue* obj) {
    19. return (obj->back+1)%(obj->k+1) == obj->front;
    20. }
    21. bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    22. if(myCircularQueueIsFull(obj))
    23. return false;
    24. obj->a[obj->back]=value;
    25. ++obj->back;
    26. (obj->back) %=(obj->k+1);
    27. return true;
    28. }
    29. bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    30. if(myCircularQueueIsEmpty(obj))
    31. return false;
    32. ++obj->front;
    33. obj->front %=(obj->k+1);
    34. return true;
    35. }
    36. int myCircularQueueFront(MyCircularQueue* obj) {
    37. if(myCircularQueueIsEmpty(obj))
    38. return -1;
    39. return obj->a[obj->front];
    40. }
    41. int myCircularQueueRear(MyCircularQueue* obj) {
    42. if(myCircularQueueIsEmpty(obj))
    43. return -1;
    44. return obj->a[(obj->back+obj->k)%(obj->k+1)];
    45. }
    46. void myCircularQueueFree(MyCircularQueue* obj) {
    47. free(obj->a);
    48. free(obj);
    49. }

  • 相关阅读:
    ElementUI浅尝辄止36:Input 输入框
    Linux_day12_LVM
    微信公众号开发与本地调试详细教程
    [Web]域名备案
    JAVA基础——【笔记】14.集合
    Flip技术
    Html和Markdown中的空格,       以及   ‌ ‍三种Unicode空格
    MySql安全加固:无关或匿名帐号&是否更改root用户&避免空口令用户&是否加密数据库密码
    OpenAI Assistants-API简明教程
    vue页面报Expected indentation of 2 spaces but found 4.eslintindent
  • 原文地址:https://blog.csdn.net/2301_76618602/article/details/134524524