循环队列的设计

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

来源:力扣(LeetCode)

这是来自力扣的一道题,要求模拟一个循环队列,包含以上的功能。这里的循环队列有固定的长度为k,队满就不能再入数据。

一般队列都是用链表来模拟实现的,那么这里的循环队列也可以用链表实现,只不过要注意一些地方:

 

这种情况下,如果设置头尾指针front和rear,k==4,那么此时队列判空和判满的条件都是rear==front,所以为了优化这个情况,我们可以多开一个空间来便于判断队空和队满:

此时k==5,当rear==front时为队空,rear->next==front时为队满。但是这种情况又有一个问题就是队尾该如何取,已知rear是在存完数据后++,所以一直指向空位置,在单链表要想取rear的前一个位置就要再多加一个指针rearpre来取rear前一个位置或者也可以用双向链表来实现。

而如果这里使用数组来模拟这个队列,思想是和链表一样的,而且操作更加简单,所以这里我选择用数组来模拟:

class MyCircularQueue {
public:
    MyCircularQueue(int k) {
        a = (int*)malloc(sizeof(int) * (k + 1)); //比原来多开一个空间
        front = 0;
        rear = 0;
        m = k;
    }

    bool enQueue(int value) {
        if (isEmpty())
        {
            a[rear] = value;
            rear++;
            return true;
        }
        if (isFull())
            return false;
        if (rear == m + 1)
        {
            rear = 0;
            a[rear] = value;
            rear++;
        }
        else
        {
            a[rear] = value;
            rear++;
        }
        return true;
    }

    bool deQueue() {
        if (isEmpty())
            return false;
        if (front == m + 1)
        {
            front = 0;
            front++;
        }
        else
        {
            front++;
        }
        return true;
    }

    int Front() {
        if (isEmpty())
            return -1;
        return a[front];
    }

    int Rear() {
        if (isEmpty())
            return -1;
        return a[(rear - 1 + m + 1) % (m + 1)]; 取模防止越界
    }

    bool isEmpty() {
        return rear == front;
    }

    bool isFull() {
        return (rear + 1) % (m + 1) == front; //取模防止越界
    }
    int* a; //模拟循环链表的队列
    int front; //指向头
    int rear; //指向尾
    int m; //要求数组长度
};

用数组模拟判断队满时要注意用rear+1==front判断有一种特殊情况会越界:

 此时的rear+1会到下标为5的位置处去导致越界,可以通过特殊处理解决,也可以改一下判断条件为(rear + 1) % (k + 1) == front,这样rear在下标4以前的位置模5不会改变,而在下标为4的地方便会回到下标为0处。

判断队尾时用rear-1也有一种特殊情况会越界:

此时rear-1会到下标为-1的位置导致越界 ,这里也可以通过特殊处理解决,不过也同样可以改变判断条件为(rear-1+k+1) % (k+1)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

双葉Souyou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值