手把手教你实现一个循环队列(C语言)

简介: 手把手教你实现一个循环队列(C语言)

这是一道leetcode关于队列的经典题:

a856a557b8264e5394a6fca53705fa32.png

思路:

大家注意这个题目要求,这个队列是定长的,如果满了则不能再添加数据。那么我们设计一个队头front和队尾rear,每次添加数据rear向后走,这时就有一个问题,怎么区分空和满呢?当最后一个数据入队列之后,由于这是个循环队列,rear会回到front这个位置。那么比较好的一种方法就是多开一个空间,满的条件是rear+1==front。

81ef6e0300d34628beac33c094872e40.png d942dff2ea3247ac8e24f4837add2754.png 实现:


循环队列的定义:

typedef struct {
    int K;
    int* a;
    int front;
    int rear;
} MyCircularQueue;

循环队列的创建:

为队列和数组创建空间,需要注意的是数组a的空间是K+1个,要多开一个.

MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    //多开辟一个空间,用以区分空和满
    obj->K=k;
    obj->a=(int*)malloc(sizeof(int)*(obj->K+1));
    obj->front=0;
    obj->rear=0;
    return obj;
}

判断队列是否为空:

如果front==rear则为空。

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    return obj->front==obj->rear;
}

判断队列是否为满:

如果rear+1==front则为满,或者说(rear+1)%(k+1)==front。

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    return (obj->rear+1)%(obj->K+1)==obj->front;
}

数据入队列:

先判断队列是否满了,满了则返回false。如果不满则在rear这个位置上添加数据,再把rear++,再将rear=rear%(k+1)。

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    if(myCircularQueueIsFull(obj))
        return false;
    obj->a[obj->rear]=value;
    obj->rear++;
    obj->rear=(obj->rear)%(obj->K+1);
    return true;
}

数据出队列:

判断一下队列是否为空,空则返回false。出队列直接将front++即可,再将front=front%(k+)。

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
        return false;
    obj->front++;
    obj->front=(obj->front)%(obj->K+1);
    return true;
}

取队列头部数据:

int myCircularQueueFront(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
        return -1;
    else
        return obj->a[obj->front];
}

取队列尾部数据:

这里需要注意,尾部数据的位置是在rear-1这个位置,所以rear-1+k+1就是rear+k.

int myCircularQueueRear(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
        return -1;
    else
        return obj->a[(obj->rear+obj->K)%(obj->K+1)];
}

销毁队列:

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

完整代码:

typedef struct {
    int K;
    int* a;
    int front;
    int rear;
} MyCircularQueue;
MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    //多开辟一个空间,用以区分空和满
    obj->K=k;
    obj->a=(int*)malloc(sizeof(int)*(obj->K+1));
    obj->front=0;
    obj->rear=0;
    return obj;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    return obj->front==obj->rear;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
    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->rear)%(obj->K+1);
    return true;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
        return false;
    obj->front++;
    obj->front=(obj->front)%(obj->K+1);
    return true;
}
int myCircularQueueFront(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
        return -1;
    else
        return obj->a[obj->front];
}
int myCircularQueueRear(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
        return -1;
    else
        return obj->a[(obj->rear+obj->K)%(obj->K+1)];
}
void myCircularQueueFree(MyCircularQueue* obj) {
    free(obj->a);
    free(obj);
}

这次的分享到这里就结束了,感谢大家的阅读!

相关文章
|
8月前
|
存储 安全 编译器
c语言从入门到实战——初识指针
C语言指针是一种变量,它存储了另一个变量的内存地址。通过指针,我们可以直接访问内存中的数据,从而实现灵活的数据操作。 指针是编程中的一个概念,它存储的是内存地址,指向某个变量。通过指针,可以直接访问和操作内存中的数据,提高程序效率。但使用指针时需小心,避免空指针和野指针等问题,确保程序安全稳定。
88 0
|
8月前
|
存储
手把手设计C语言版循环队列(力扣622:设计循环队列)
手把手设计C语言版循环队列(力扣622:设计循环队列)
62 0
|
8月前
|
存储 编译器 C语言
c语言进阶部分详解(指针初阶)
c语言进阶部分详解(指针初阶)
85 0
|
存储 小程序 编译器
【初阶C语言】数组
数组在C语言中是一个比较重要的知识点,学会它便可以完成很多有意思的小程序,比如三子棋和扫雷, 数组分为一维数组和二维数组,然后学习数组又拆分成创建、初始化、传参和使用,还有需要注意的地方,如数组越界和数组在内存中的存储。那我们现在先从一维数组开始吧,二维数组跟一维数组也是同理。
75 0
|
C语言 C++
C语言指针进阶笔试题讲解
C语言指针进阶笔试题讲解
84 1
|
1月前
|
存储 算法 C语言
【C语言】深入浅出:C语言链表的全面解析
链表是一种重要的基础数据结构,适用于频繁的插入和删除操作。通过本篇详细讲解了单链表、双向链表和循环链表的概念和实现,以及各类常用操作的示例代码。掌握链表的使用对于理解更复杂的数据结构和算法具有重要意义。
696 6
|
8月前
|
存储 C语言
设计循环队列(c语言)
设计循环队列(c语言)
|
存储 C语言 C++
一步一步教你从零开始写C语言链表
一步一步教你从零开始写C语言链表
106 0
|
存储 编译器 程序员
【C语言初阶】 数组
【C语言初阶】 数组
108 0
|
存储 C语言
LeetCode 设计循环队列(C语言)
LeetCode 设计循环队列(C语言)