设计循环队列--C语言

1.设计要求

设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。
你的实现应该支持如下操作:

MyCircularQueue(k): 构造器,设置队列长度为 k 。
Front: 从队首获取元素。如果队列为空,返回 -1 。
Rear: 获取队尾元素。如果队列为空,返回 -1 。
enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。
deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。
isEmpty(): 检查循环队列是否为空。
isFull(): 检查循环队列是否已满。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/design-circular-queue

2.设计思路流程

1.我们先采用链表的方法实现,使链表的尾结点的指针指向头节点,这样就形成了一个循环链表,插入数据时插入到尾结点,采用尾插法。但是这样存在一个问题:空和满的条件是一样的,无法判断空还是满,此时判断条件都是head==tail。
在这里插入图片描述

2.上述方法不可取,我们空出来一个结点的方法,比如说有4个结点,但是我们只存储三个数据。判断空的条件还是head==tail,但是我修改判断满的条件为尾结点的下一个是头节点为满。插入数据我们依然采用尾插法。
在这里插入图片描述
3.以上方法均采用的是链表的形式,链表上在物理结果和逻辑结构上都是连续的,都是循环的,这使读者更加直观了解循环队列的实现。但是循环队列所存储的元素是一定的k个,不需要动态开辟内存空间,我们可以考虑采用顺序表来实现,顺序表在物理结构上并不连续,但是在逻辑结构上是连续的。
在这里插入图片描述

3.代码实现

typedef struct 
{
    int* a;
    int k;//队列对多能存储多少数据
    int front;//头
    int tail;//尾(队尾数据下一个)
} MyCircularQueue;

(1)MyCircularQueue(k): 构造器,设置队列长度为 k

MyCircularQueue* myCircularQueueCreate(int k) 
{
    MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    obj->a=(int*)malloc(sizeof(int)*(k+1));
    obj->front=0;
    obj->tail=0;
    obj->k=k;
    return obj;
}

(2)Front: 从队首获取元素。如果队列为空,返回 -1

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

(3)Rear: 获取队尾元素。如果队列为空,返回 -1

int myCircularQueueRear(MyCircularQueue* obj) 
{
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    else
    {
        int tailPrev=obj->tail-1;
        if(tailPrev==-1)
        {
            tailPrev=obj->k;
        }
        return obj->a[tailPrev];
    }
}

(4)enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真

在这里插入图片描述

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) 
{
    if(myCircularQueueIsFull(obj))
    {
        return false;
    }
    else
    {
        obj->a[obj->tail]=value;
        ++obj->tail;
        if(obj->tail==obj->k+1)
        {
            obj->tail=0;
        }
    }
    return true;
}

(5)deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真

在这里插入图片描述

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

(6)isEmpty(): 检查循环队列是否为空

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

(7)isFull(): 检查循环队列是否已满

bool myCircularQueueIsFull(MyCircularQueue* obj) 
{
    int tailNext=obj->tail+1;
    if(tailNext==obj->k+1)
    {
        tailNext=0;
    } 
    return tailNext==obj->front;
}

(8)Free(): 销毁循环队列

void myCircularQueueFree(MyCircularQueue* obj) 
{
    free(obj->a);
    free(obj);
}
  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值