活用下标,使用数组实现循环队列

题目

思路

创建一个结构体变量维护一块数组空间,使用数组实现循环队列。

为了区分队列满和空:

方法1:存储k个数据时,开辟k+1个空间,始终空置一个空间不存放数据。

方法2:通过size统计队列中的元素个数。

代码实现

定义结构体

有了类型就知道变量的内存大小和该往内存中存放什么数据(如是结构体,就知道存放哪些成员)。

使用front、rear、k和a维护这块循环队列空间。

front指向队头元素。

rear指向队尾元素的下一个位置,也就是始终置空的位置。rear-1指向队尾元素。

k代表队列长度。

a存放数据的数组。

typedef struct 
{
    int front; 
    int rear;
    int k;
    int* a; //存放数据的数组
} MyCircularQueue;

创建结构体

为结构体申请内存和初始化成员。


检查是否为空

判断的标准就是front是否等于rear,如果等于返回true,否则返回false。

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

检查是否为满

判断的标准就是rear的下一个位置是front。

bool myCircularQueueIsFull(MyCircularQueue* obj) 
{
    //检查标准就是:rear的下一个位置就是front
    return (obj->rear+1) % (obj->k+1) == obj->front;
}

插入元素

插入之前,检查队列是否为满。

实现插入的方式就是在下标rear的位置,填入数据。

但rear可能越过最大下标k(多开了1个空间),当rear等于k+1时,应该回到下标0的位置。

rear从6减小到0,通过求余实现。

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) 
{
    //检查队列是否为满
    if(myCircularQueueIsFull(obj))
    {
        return false;
    }

    //在rear位置插入元素
    obj->a[obj->rear++] = value;
    
    //避免越界
    // obj->rear = (obj->rear) % (obj->k+1);
    obj->rear %= (obj->k+1);

    return true ;
}

删除元素

删除之前,检查队列是否为空。

实现删除的方式就是把下标front往左移动一个位置。

但front可能越过最大下标k(多开了1个空间),当front等于k+1时,应该回到下标0的位置。

front从6减小到0,通过求余实现。

bool myCircularQueueDeQueue(MyCircularQueue* obj) 
{
    //检查队列是否为空
    if (myCircularQueueIsEmpty(obj))
    {
        return false;
    }  

    obj->front++;
    //避免越界
    obj->front %= (obj->k+1);

    return true;
}

获取队头元素

直接返回下标front的元素。

int myCircularQueueFront(MyCircularQueue* obj) 
{
    //检查队列是否为空
    if (myCircularQueueIsEmpty(obj))
    {
        return -1;
    } 

    return obj->a[obj->front];
}

返回队尾元素

方法1:创建双向链表。

方法2:增加一个rearPrev指针。

方法3:遍历获取队尾元素。

方法4:返回下标rear-1位置的元素。

但是rear等于0时,rear-1会越界,需要返回队尾下标k的位置。

rear从0增大到5,通过增大rear实现。

int myCircularQueueRear(MyCircularQueue* obj) 
{
    //检查队列是否为空
    if (myCircularQueueIsEmpty(obj))
    {
        return -1;
    } 

    // return obj->arr[obj->rear-1]; //可能越界
    //使得rear-1不等于-1,而是回到下标5的位置
    return (obj->rear + obj->k) % (obj->k+1);
}

释放内存

先释放堆数组,再释放结构体。

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

申请了堆空间,在结束函数调用前,检查是否释放内存。

统一计算格式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值