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

题目

思路

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

为了区分队列满和空:

方法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
    评论
以下是用C语言实现循环队列的代码示例: ```c #include <stdio.h> #include <stdlib.h> #define MAX_SIZE 5 typedef struct { int data[MAX_SIZE]; int front; int rear; } Queue; void initQueue(Queue *q) { q->front = 0; q->rear = 0; } int isFull(Queue *q) { return (q->rear + 1) % MAX_SIZE == q->front; } int isEmpty(Queue *q) { return q->front == q->rear; } void enQueue(Queue *q, int value) { if (isFull(q)) { printf("Queue is full.\n"); return; } q->data[q->rear] = value; q->rear = (q->rear + 1) % MAX_SIZE; } int deQueue(Queue *q) { if (isEmpty(q)) { printf("Queue is empty.\n"); return -1; } int value = q->data[q->front]; q->front = (q->front + 1) % MAX_SIZE; return value; } int main() { Queue q; initQueue(&q); enQueue(&q, 1); enQueue(&q, 2); enQueue(&q, 3); enQueue(&q, 4); enQueue(&q, 5); enQueue(&q, 6); // 队列已满,无法入队 printf("%d\n", deQueue(&q)); // 输出:1 printf("%d\n", deQueue(&q)); // 输出:2 printf("%d\n", deQueue(&q)); // 输出:3 printf("%d\n", deQueue(&q)); // 输出:4 printf("%d\n", deQueue(&q)); // 输出:5 printf("%d\n", deQueue(&q)); // 队列已空,无法出队,输出:-1 return 0; } ``` 以上代码中,我们使用了一个结构体`Queue`来表示循环队列,其中`data`数组用于存储队列元素,`front`和`rear`分别表示队头和队尾的下标。`initQueue`函数用于初始化队列,`isFull`和`isEmpty`函数分别用于判断队列是否已满和是否为空。`enQueue`函数用于入队,`deQueue`函数用于出队。在`enQueue`和`deQueue`函数中,我们使用了取模运算来实现循环队列的特性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值