力扣刷题笔记--设计循环队列(C语言)

1.题目要求

力扣刷题笔记--设计循环队列(C语言)_第1张图片

 

题目要求实现指定长度的循环列表,其队尾必须链接在队首之后,且要满足 FIFO(先进先出)原则。

2.基本思路

如果使用单向链表实现这道题,则会出现不好找尾的问题,删除尾之后,前一个指针就成了野指针,而且还会出现无法区分队列满或空的情况,在队列满和空的时候,头指针和尾指针都指向一个位置。

  为了方便访问尾的前一个元素,本篇文章采用数组实现循环队列,为了使头和尾指针在列表满与列表空时区分开,在开辟数组时,选择多开一个位置,该位置不存储有效数据。

3.代码实现

typedef struct {
    int* a;//数组实现队列
    int k;//记录队列有效数据个数
    int head;//头下标,指向队列的首元素
    int tail;//尾下标,指向队列的尾元素的下一个
} MyCircularQueue;


MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    obj->a = malloc(sizeof(int)*(k+1));//创建k+1长度的数组,最多存储k个有效数据
    obj->head = obj->tail = 0;
    obj->k = k;

    return obj;
}

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    //如果头和尾的值相同,说明队列为空
    if(obj->head == obj->tail)
        return true;
    else
        return false;
}

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    //记录tail的下一个数据
    int next = obj->tail+1;
    //如果tail下一个值为k+1,说明tail已经在数组边界上,下一步next是0而不是tail+1
    if(next == obj->k+1)
    {
         next = 0;
    }

    //如果tail的下一个值就是head,说明已满
    if(next == obj->head)
        return true;
    else
        return false;
}

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    //检查队列是否已满
    if(myCircularQueueIsFull (obj))
        return false;
    //将数据尾插到tail上,更新tail
    obj->a[obj->tail] = value;
    obj->tail++;
    //如果尾的值为k+1,说明已经超出数组边界,需要回到下标0的位置
    if(obj->tail == obj->k+1)
        obj->tail=0;
    
    return true;
}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    //判断队列是否为空
    if(myCircularQueueIsEmpty(obj))
        return false;
    //队头出数据,头指针往后走一步
    obj->head++;
    //如果头的值为k+1,说明已经超出数组边界,需要回到下标0的位置
    if(obj->head == obj->k+1)
        obj->head=0;

    return true;
}

int myCircularQueueFront(MyCircularQueue* obj) {
    //判断队列是否为空
    if(myCircularQueueIsEmpty(obj))
        return -1;
    //返回数组head位置的数据
    return obj->a[obj->head];

}

int myCircularQueueRear(MyCircularQueue* obj) {
     //判断队列是否为空
    if(myCircularQueueIsEmpty(obj))
        return -1;
    //记录尾的前一个
    int prev = obj->tail-1;
    //如果tail在位置0,则前一个位置在k处而不是-1
    if(obj->tail == 0)
        prev = obj->k;
    
    return obj->a[prev];

}


void myCircularQueueFree(MyCircularQueue* obj) {
    free(obj->a);
    free(obj);
}

你可能感兴趣的:(leetcode刷题笔记,leetcode,算法,职场和发展)