数据结构—循环队列

数据结构---循环队列

循环队列

一般在操作系统课程讲解生产者消费者模型时可以就会使用循环队列。环形队列可以使用数组实现,也可以使用循环链表实现。

为了能使下标Qrear = Qfront来区别队空还是队满,我们常常认为以下左图为队空,右图为队满的情况。a1到a7为7个有效数据,有效数据k个;左图初始空队列状态,我们认为Qrear=Qfront=0,右图此时满队列的状态,Qrear=7,Qfront=0

设计循环队列

结构体的创建

c 复制代码
typedef struct {
    int*a;//用动态数组实现
    int front;//头的下标
    int rear;//尾的下标
    //所以front和rear的取值都是0~k
    int k;//队列长度,有效数据长度为k
} MyCircularQueue;

循环队列的初始化

c 复制代码
MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    if(NULL == obj)//动态开辟结构体指针(销毁空间时也需free)
    {
        perror("malloc obj faile\n");
        return NULL;
    }
    obj->front = obj ->rear = 0;//初始队列元素为空,头尾在一起下标都为0
    obj->a = (int*)malloc(sizeof(int)*(k+1));//动态数组开辟k+1个空间,因为实际队列长度要比有效数据长度多一个空间
    if(obj->a == NULL)
    {
        perror("malloc obj->a faile");
        return NULL;
    }
    obj->k= k;//队列有效数据长度
    return obj;
}

判空

因为这是循环队列,在经过不断的插入删除的过程中,rear和front会不断地变换位置,所以判空条件就是判断他俩是否相等而不是他俩是否都为0

c 复制代码
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    return obj->front == obj->rear;//若rear和front相等即为空
}

判满

判满条件只需要看(rear+1)%(k+1)==front就好了

c 复制代码
//判满
bool myCircularQueueIsFull(MyCircularQueue* obj) {
    return (obj->rear+1) % (obj->k+1) == obj->front;
}

插入(尾插)

c 复制代码
boolmyCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    //有插入就要判断空间问题,判断队列是否满了
    if(myCircularQueueIsFull(obj))
    {
        return false;//插入失败返回false
    }
    obj->a[obj->rear++] = value;
    obj->rear %= obj->k+1;//rear为下标取值范围为0~k,所以这里限制以下rear的取值范围
    return true;
}

出队列(头删)

删除要判断是否为空队列,空队列不可以删除;头删原理就是,自增front,同样在进行头删的时候,因为front的自增,在动态数组ak到a0之间的过渡也需要对front取值范围的限制。

c 复制代码
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    //删除就要判空
    if(myCircularQueueIsEmpty(obj))
    {
        return false;
    }
    ++obj->front;
    obj->front %= obj->k+1;
    return true;
}

取队头元素

c 复制代码
int myCircularQueueFront(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;//队列为空返回-1
    }
    return obj->a[obj->front];
}

取队尾元素

c 复制代码
int myCircularQueueRear(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;//队列为空返回-1
    }
    return obj->a[(obj->rear-1+obj->k+1) % (obj->k+1)];
}

空间的销毁

c 复制代码
//空间的销毁
void myCircularQueueFree(MyCircularQueue* obj) {
    free(obj->a);
    obj->a = NULL;//防止野指针形成
    free(obj);
    obj = NULL;
}
相关推荐
不会就选b4 小时前
算法日常・每日刷题--<优先级队列>2
数据结构·算法
LuminousCPP5 小时前
单链表专题(三)-刷题复盘篇:从快慢指针到环形链表 II 数学推导
数据结构·经验分享·笔记·学习·算法·链表
ChaoZiLL5 小时前
二叉树经典例题
数据结构·算法
三克的油5 小时前
算法基础-1
数据结构·c++·算法
一米阳光86616 小时前
软考(中级)软件设计师核心笔记(8)数据结构——树与二叉树
数据结构·笔记·职场发展·软考·软件设计师·中级职称
依然鸣6 小时前
PTA团体程序设计天梯赛L2真题讲解L2-005-008
开发语言·数据结构·c++·算法·深度优先·pat考试·图论
imaol17 小时前
数据结构--树
数据结构
Tongzhi20267 小时前
通芝科技无感考勤一体机:软硬一体,开箱即用
数据结构·数据库·科技·算法·均值算法·数据库开发
linux-hzh8 小时前
百日算法修炼 · Day 09
数据结构·算法·排序算法
淡海水9 小时前
C#与常用数据结构源码剖析-全篇导览
开发语言·数据结构·unity·面试·职场和发展·c#