环形队列介绍:
在实际中,我们会用到一种特殊的队列,即环形队列,也可以叫做循环队列。在操作系统中有一个生产者消费者模型使用的就是循环队列。循环队列可以用数组实现,也可以用链表实现。
循环队列仍是一种线性结构,它是基于队列先进先出的特性在队尾连接队头实现的,在逻辑结构上就构成了一个环状,所以被叫做环形队列、循环队列。
循环队列的一个有点是,我们可以不断循环的利用这个队列的空间,一个普通的队列,在元素满载之后就不能再进行元素插入了,但是环形队列可以。不过会将之前的值覆盖,所以并不是所有条件下都适用。
操作系统中的生产者消费者模型,就是典型的循环队列。用餐厅举例就是,这个餐厅只有10张桌子(10个空间),我这10张桌子没有满,顾客就可以直接上桌点菜(直接进行元素插入)。但是如果桌子使用完了,那就只有等之前的顾客吃完饭之后,后来的顾客才能上桌点菜(对首的元素已经使用完,且之后不在使用,这块空间就能够再次使用了)。
题目链接:
代码实现:
typedef struct { int* a; int head; int tail; int k; } MyCircularQueue; MyCircularQueue* myCircularQueueCreate(int k) { MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue)); //多开辟一个空间,用于判满 obj->a = (int*)malloc(sizeof(int) * (k + 1)); obj->head = obj->tail = 0; obj->k = k; return obj; } bool myCircularQueueIsEmpty(MyCircularQueue* obj) { return obj->tail == obj->head; } bool myCircularQueueIsFull(MyCircularQueue* obj) { return ((obj->tail+1) % (obj->k+1)) == obj->head; } bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) { if(myCircularQueueIsFull(obj)) return false; obj->a[obj->tail++] = value; obj->tail %= (obj->k+1); return true; } bool myCircularQueueDeQueue(MyCircularQueue* obj) { if(myCircularQueueIsEmpty(obj)) return false; obj->head++; obj->head %= (obj->k+1); return true; } int myCircularQueueFront(MyCircularQueue* obj) { if(myCircularQueueIsEmpty(obj)) return -1; else return obj->a[obj->head]; } int myCircularQueueRear(MyCircularQueue* obj) { if(myCircularQueueIsEmpty(obj)) return -1; else return obj->a[(obj->tail + obj->k) % (obj->k + 1)]; } void myCircularQueueFree(MyCircularQueue* obj) { free(obj->a); free(obj); } /** * Your MyCircularQueue struct will be instantiated and called as such: * MyCircularQueue* obj = myCircularQueueCreate(k); * bool param_1 = myCircularQueueEnQueue(obj, value); * bool param_2 = myCircularQueueDeQueue(obj); * int param_3 = myCircularQueueFront(obj); * int param_4 = myCircularQueueRear(obj); * bool param_5 = myCircularQueueIsEmpty(obj); * bool param_6 = myCircularQueueIsFull(obj); * myCircularQueueFree(obj); */