LeetCode 622.设计循环队列 C写法
思路🤔:
首先我们要清楚循环队列的逻辑结构,队尾应该在队头的前一位停下,否则就会首尾相连。其次这题要求返回队尾元素,而用链表不好找尾,所以用数组来设计该题队列比较合适。
创建三个变量,一个存储头的下标(front),一个存储尾的下标(rear),一个存储队列长度(k)。入队rear移动,出队front移动,如果rear等于front就为空,rear+1等于front就满队。当rear或者front走了一个循环,那么可以取模进行置0,又从头开始走,具体思路可以看代码。
代码🔎:
typedef struct { int* a; int front; //头 int rear; //尾 int k; //队列长度 } MyCircularQueue; MyCircularQueue* myCircularQueueCreate(int k) { MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue)); if(obj == NULL) { perror("malloc fail!"); return NULL; } obj->a = (int*)malloc(sizeof(int) * (k + 1)); //多开一个空间,否则会首尾相连 obj->front = 0; obj->rear = 0; obj->k = k; return obj; } bool myCircularQueueIsEmpty(MyCircularQueue* obj) { return obj->rear == obj->front; //首尾相连即为空 } bool myCircularQueueIsFull(MyCircularQueue* obj) { //rear+1 == front时表示已经满了 //所以这里考虑到循环的情况用rear+1取模 return (obj->rear + 1) % (obj->k + 1) == obj->front; } bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) { if(myCircularQueueIsFull(obj)) //满了就不能入队 return false; obj->a[obj->rear] = value; obj->rear++; obj->rear %= (obj->k + 1); //当尾已经走到最后,取模置回0,不为0取模还是等于原数 return true; } bool myCircularQueueDeQueue(MyCircularQueue* obj) { if(myCircularQueueIsEmpty(obj)) //如果为空,就直接返回false return false; obj->front++; //头向前移动即可 obj->front %= (obj->k + 1); //当头已经走到最后,取模置回0 return true; } int myCircularQueueFront(MyCircularQueue* obj) { if(myCircularQueueIsEmpty(obj)) return -1; return obj->a[obj->front]; } int myCircularQueueRear(MyCircularQueue* obj) { if(myCircularQueueIsEmpty(obj)) return -1; //取队尾实际是访问rear的前一个数据,这里要防止rear-1为负的情况 //原式为rear - 1 + k + 1,化简后为rear+k return obj->a[(obj->rear + obj->k) % (obj->k + 1)]; } void myCircularQueueFree(MyCircularQueue* obj) { free(obj->a); free(obj); }