【问题标题】:Full / Empty Buffer distinction in Circular Queue循环队列中的Full / Empty Buffer区别
【发布时间】:2014-11-14 15:56:38
【问题描述】:

在循环队列的数组实现中,如果前面指向第一个元素之前的一个槽,后面指向最后一个元素,那么我们面临如何识别队列是满还是空的问题。

为了解决这个问题,我们要么使用计数器,要么在缓冲区中浪费一个空间。

我正在考虑以下方法。请纠正我哪里出错了,如果不是,请告诉我这是否比上述解决方案更好/更差。

  1. 前面指向第一个元素,后面指向最后一个元素;
  2. 具有检查队列是否仅剩 1 个元素的功能;
  3. 如果我们要对最后一个元素进行出队,则将前后设为 -1;
  4. 如果前后均为-1,isEmpty() 将为真;
  5. 如果 front = (rear + 1) % size,isFull 将为真。

【问题讨论】:

    标签: arrays algorithm data-structures queue circular-buffer


    【解决方案1】:

    这种方法在逻辑上没有太大的错误。您将frontrear 中的负值视为一种指示队列为空的标志。假设您更新frontrear 的逻辑将值保持在0..size 范围内,您只需将其中一个设置为超出该范围即可指示队列为空。

    考虑这个替代方案。许多循环队列使用frontrear 索引作为无符号值,size 作为 2 的幂。它们的值的更新总是递增,并且允许它们环绕。这避免了调整这些索引的复杂逻辑。因为索引是无符号的,即使它们环绕,差分算法也能正常工作以确定元素的数量。

    即使索引在增量时环绕,模数的工作原理是 size 是 2 的幂。这确保环绕不会影响模数计算。

    unsigned front_ = 0, rear_ = 0;
    Type q_[SIZE];
    
    unsigned getCount () { return rear_ - front_; }
    bool isEmpty () { return getCount() == 0; }
    bool isFull () { return getCount() == SIZE; }
    bool enQ (Type val) {
        bool result = !isFull();
        if (result) q_[rear_++ % SIZE] = val;
        return result;
    }
    bool deQ (Type *val) {
        bool result = !isEmpty();
        if (result) *val = q_[front_++ % SIZE];
        return result;
    }
    

    【讨论】:

    • 然而,无符号整数有上限。当它达到上限时,只有天知道会发生什么。
    • @guo : 使用unsigned 的意义在于它的溢出行为在 C 标准中得到了很好的定义。
    猜你喜欢
    • 2021-09-29
    • 2017-04-14
    • 2020-06-23
    • 2017-12-26
    • 1970-01-01
    • 2012-11-03
    • 2017-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多