设计循环队列--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。
设计循环队列--C语言_第1张图片

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

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): 向循环队列插入一个元素。如果成功插入则返回真

设计循环队列--C语言_第4张图片

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(): 从循环队列中删除一个元素。如果成功删除则返回真

设计循环队列--C语言_第5张图片

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);
}

你可能感兴趣的:(数据结构,链表,队列,数据结构)