手撕数据结构—循环队列
创始人
2025-06-01 11:45:02
0

Tips

  1. 在一个函数的接口里面,如果说它的返回值是一个地址的话,那么往往来讲,你这函数里面的内存空间的开辟必须是要向堆区去申请的malloc之流

  1. 栈的结构是先进后出,队列的结构是先进先出

  1. 无论是在main函数内部还是外部,编译器的话,它只会向上找,它不可能向下找,因为它要提高它的编译速率

  1. 字符与整数之间可以灵活转化,因为字符其实本质上就是ACSII码,就是整型。

循环队列

  1. 循环队列也是队列的一种,他也要求是先进先出。

  1. 循环队列就是说队列当中整个数据的总数是确定的,然后在这个结构当中可以转圈圈,但是他毕竟也是队列的一种,因此他也是符合队列的特性,也就是说是先进先出。只不过他的空间可以重复利用,你就可以把它想象成转圈圈。它的head与front都可以在圈圈当中不断的转动,它的主要好处就在于空间可以重复利用

  1. 对于现在这个循环队列而言,就是说在最开始所有空间都应该被开辟出来,无论你是用数组模拟还是用链表去模拟,当然要开多少空间(实际上就取决于你最多能存多少个数据)这个的话一开始会告诉你的

  1. 在设计循环队列的时候,我们用的是数组去模拟循环队列,但是对于这个数组的话,需要进行一个额外的处理,因为当这个循环队列为空,你会发现两个指针是指向一起的,然后当这个循环队列满的时候,你又会发现两个指针是指向一起的,这时候为了以示区分的话,有两种方法:第一种方法的话就是说在结构体里面加一个结构体成员size去维护一下;第二种方式的话就是在数组的基础之上,额外开一个元素的空间,这个空间里面不存放任何数据,是专门用来区分上面讲的两种情况。

  1. 然后对于两个结构体成员front和rear的话,在数组里面是不能够越界的,所以说如果说走到头的话,需要从起点开始再走,这之后的话,你只需要给他取余上数组的长度就可以了。

  1. 在这边还是得强调一下,就是说这个front和rear这两个的话都是数组的下标,也是结构体的成员,在最初始状态的话,两个东西都是0。然后当有数据插入的时候,我改变的是rear,必须要弄清楚的是:rear是末尾数据的下一个元素的下标;然后等有数据需要从队头弹出的时候,我改变的是front,也就是说把front向后移一位。

  1. 然后再额外的强调一下什么时候这个循环队列是空?当rear与front一样的时候,什么时候这个循环队列是满的(因为在之前也提到过这个循环队列当中能存多少个数据k这事先已经告诉你的,是限定死的),当rear+1为front(现在不考虑取余),这时候说明这个循环队列是满的。


622. 设计循环队列 - 力扣(LeetCode)

typedef int MyQDataType;
typedef struct 
{int front;int rear;int k;MyQDataType* pp;
} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k) 
{MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));if (obj==NULL){perror("malloc fail");return NULL;}obj->pp = (MyQDataType*)malloc(sizeof(MyQDataType)*(k+1));if (obj->pp==NULL){perror("malloc fail");return NULL;}obj->front=0;obj->rear=0;obj->k=k;return obj;
}bool myCircularQueueIsFull(MyCircularQueue* obj) 
{assert(obj);int num=(obj->rear+1)%(obj->k+1);return num==obj->front;
}bool myCircularQueueIsEmpty(MyCircularQueue* obj) 
{assert(obj);return obj->front==obj->rear;
}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) 
{assert(obj);if (myCircularQueueIsFull(obj)){return false;}obj->pp[obj->rear]=value;int num=(obj->rear+1)%(obj->k+1);obj->rear=num;return true;
}bool myCircularQueueDeQueue(MyCircularQueue* obj) 
{assert(obj);if (myCircularQueueIsEmpty(obj)){return false;}int num=(obj->front+1)%(obj->k+1);obj->front=num;return true;
}int myCircularQueueFront(MyCircularQueue* obj) 
{assert(obj);if (myCircularQueueIsEmpty(obj)){return -1;}return obj->pp[obj->front];
}int myCircularQueueRear(MyCircularQueue* obj) 
{assert(obj);if (myCircularQueueIsEmpty(obj)){return -1;}return obj->pp[(obj->rear-1+obj->k+1)%(obj->k+1)];
}void myCircularQueueFree(MyCircularQueue* obj) 
{assert(obj);free(obj->pp);obj->pp=NULL;obj->front=0;obj->rear=0;free(obj);
}

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...