循环队列的实现(c语言)

前言

循环队列是队列的一种特殊的结构,在生产者------消费者模型中常常使用它, 它在逻辑上是一个环形的连续的结构。在物理可以使用数组来实现。

目录

1.循环队列的逻辑结构

2.空的循环队列和满的循环队列

3.循环队列插入和删除

4.代码实现


1.循环队列的逻辑结构

循环队列在逻辑上连续的。

2.空的循环队列和满的循环队列

因为是采用数组进行队列的实现的,如果是存储N个数据的队列,需要开辟N + 1个空间,当队头指针Front等于队尾指针rear时,队列为空。当队尾指针 (rear+1)%(N + 1)+ 1等于队头指针时,此时队列为满,为什么队尾指针要对N + 1进行取模运算呢,因为数组是连续的,当循环队列的尾指针走到数组的末尾时需要从数组下标为零的位置重新开始。不然数组的访问就会越界,对于头指针来说也是一样的。如图:

3.循环队列插入和删除

循环队列和队列一样,也是在队头插入数据,队尾删除数据。需要注意的是如果队头已经在数组的末尾了这时候删除掉队头的元素,队头的指针要更新到数组下标为零的元素,也就是front=(front+1)。那么下一次,队列删除的就是数组的第一个元素,如图:

插入元素也是一样的,如果rear超过了数组的长度以后要回到开始的位置。

为什么给数组开空间的时候要多开一个呢,因为始终要留出一个空位来,不然无法确定队列满的条件。

4.代码实现

cpp 复制代码
typedef struct
{
    int* _array;
    int _front;
    int _rear;
    int _k;
} MyCircularQueue;

bool myCircularQueueIsFull(MyCircularQueue* obj);//判断队列是否满了。
bool myCircularQueueIsEmpty(MyCircularQueue* obj);//判断队列是否为空

MyCircularQueue* myCircularQueueCreate(int _k) {
    MyCircularQueue* qu = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    qu->_array = (int*)malloc(sizeof(int) * (_k + 1));//多开一个
    qu->_front = qu->_rear = 0;//初始化指针
    qu->_k = _k + 1;
    return qu;
}

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value)//入数据
{
    if (obj == NULL)
        return false;//队列为空直接返回
    //如果队列满了也就不能插入元素了
    if (myCircularQueueIsFull(obj))
    {
        return false;
    }
    else
    {
        //队尾入数据
        obj->_array[obj->_rear] = value;
        ++(obj->_rear);
        obj->_rear = obj->_rear % (obj->_k);//确保rear是在合适的位置
        return true;
    }
}

bool myCircularQueueDeQueue(MyCircularQueue* obj) //队头出数据
{
    if (obj == NULL)
        return false;
    if (obj->_front == obj->_rear)//队列为空时不能出数据
        return false;
    ++(obj->_front);
    obj->_front %= (obj->_k);//确保front不会越界
    return true;
}

int myCircularQueueFront(MyCircularQueue* obj) {
    if (myCircularQueueIsEmpty(obj))//队列为空返回-1
        return -1;
    return obj->_array[obj->_front];
}
int myCircularQueueRear(MyCircularQueue* obj) {
    if (myCircularQueueIsEmpty(obj))//队列为空返回-1
        return -1;
    int tail = obj->_rear - 1;
    if (tail == -1)//如果tail为-1说明这时候rear在数组的开头,需要出队尾的元素在数组的末尾
        tail = obj->_k - 1;
    return obj->_array[tail];
}

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    return obj->_front == obj->_rear;//rear等于front时,队列为空
}
bool myCircularQueueIsFull(MyCircularQueue* obj)
{
    return ((obj->_rear + 1) % obj->_k == obj->_front); //rear + 1等于front说明队列满了
}

void myCircularQueueFree(MyCircularQueue* obj) {
    if (obj == NULL)
        return;//确保指针存在
    free(obj->_array);//先释放开辟的数组
    free(obj);
}

原题链接循环队列的实现 ,如果大家有兴趣的,尝试一下。

相关推荐
云知谷7 分钟前
【经典书籍】C++ Primer 第16章模板与泛型编程精华讲解
c语言·开发语言·c++·软件工程·团队开发
屁股割了还要学14 分钟前
【Linux入门】常用工具:yum、vim
linux·运维·服务器·c语言·c++·学习·考研
workflower31 分钟前
基本作业-管理⾃⼰的源代码
开发语言·单元测试·软件工程·需求分析·个人开发
froginwe1140 分钟前
Pandas DataFrame:深入理解数据分析的利器
开发语言
Jm_洋洋44 分钟前
【Linux系统编程】程序替换:execve(execl、execlp、execle、execv、execvp、execvpe)
linux·运维·c语言·开发语言·程序人生
小莞尔1 小时前
【51单片机】【protues仿真】基于51单片机秒表计时器系统(带存储)
c语言·stm32·单片机·嵌入式硬件·物联网·51单片机
冯诺依曼的锦鲤1 小时前
算法练习:前缀和专题
开发语言·c++·算法
闭着眼睛学算法1 小时前
【双机位A卷】华为OD笔试之【哈希表】双机位A-跳房子I【Py/Java/C++/C/JS/Go六种语言】【欧弟算法】全网注释最详细分类最全的华子OD真题题解
java·c语言·c++·python·算法·华为od·散列表
JinSoooo1 小时前
pnpm monorepo 联调:告别 --global 参数
开发语言·javascript·ecmascript·pnpm
代码改善世界1 小时前
C语言内存机制深度解析:指针运算、数组与字符串实战指南
c语言