【问题标题】:Understanding queue arithmetic in data structures理解数据结构中的队列算法
【发布时间】:2015-05-29 13:47:05
【问题描述】:

当一个元素被插入到队列中时,REAR = REAR + 1。当从队列中删除一个元素时,FRONT = FRONT + 1 当使用数组实现队列时。

现在,最初,FRONT = REAR = -1 都表示队列为空。添加第一个元素时,FRONT = REAR = 0(假设数组从 0 到 n-1)。

现在,如果我们假设FRONT = 0 and REAR = n-1 暗示队列已满。当删除一些元素时,FRONT 指针会发生变化。让我们说FRONT = 5 and REAR = 10。因此,数组位置 0 到 4 是空闲的。

当我现在想添加一个元素时,我在位置 0 处添加,FRONT 指向它。但是位置 1、2、3 和 4 是免费的。

但是,当我下次尝试插入元素时,编译器会抛出一个错误,说队列已满。由于FRONT = 0 and REAR = n-1。如何在其余位置插入并更好地理解这种排队算法?

我也想了解FRONT = REAR + 1 如何作为检查队列是否已满的条件?

【问题讨论】:

    标签: data-structures queue


    【解决方案1】:

    您想在这里循环思考相对的循环范围,而不是绝对的线性范围。因此,您不想过于关注FRONTREAR 的绝对索引/地址。它们是相互关联的,当吃豆人离开屏幕一侧时,您可以使用模算术开始回到数组的开头。当您绘制这些东西以在白板上将您的数组绘制成一个圆圈时,它会很有用。

    当我现在想添加一个元素时,我在位置 0 添加并且 FRONT 指向它。但是位置 1、2、3 和 4 是免费的。

    我认为你在这里有点倒退了。根据您的逻辑,插入会推进REAR,而不是FRONT。在这种情况下,REAR 为 0,FRONT 仍为 5。如果再次推送,REAR=1 将覆盖第一个索引,FRONT 仍为 5。

    如果N=3FRONT=2REAR=2,在推送和弹出很多次之后,我们在队列中有一个元素。当你推送(入队)时,我们设置:REAR=(REAR+1)%N 使得FRONT=2REAR=0 给我们两个元素。如果我们再次推送,FRONT=2REAR=1 给我们 3 个元素,队列已满。

    视觉上:

         R
      [..x]
         F
    
       R
      [x.x]
         F
    
        R
      [xxx]
         F
    

    ...现在我们已经吃饱了。如果来自REAR 的下一个循环索引是FRONT,则队列已满。在FRONT=2REAR=1的情况下,我们可以看到(REAR+1)%N == FRONT,所以是满的。

    如果我们此时弹出(出列),我们将设置FRONT=(FRONT+1)%N,它看起来像这样:

        R
      [xx.]
       F
    

    我也想了解一下 FRONT = REAR + 1 是如何作为检查队列是否满的条件的?

    当您使用这种循环索引时,这还不够。我们需要稍微增加一点:FRONT == (REAR+1)%N 时队列已满。我们需要模运算来处理那些“绕到另一边”的情况。

    【讨论】: