10

我正在阅读 CLRS 的基本数据结构,在阅读 Queue ADT 时,我遇到了这个:

当 Q.head = Q.tail + 1 时,队列已满,如果我们尝试将元素入队,则队列溢出。

它总是真实的吗?因为如果 Q.tail 等于 Q.length 那么我们根据文本设置 Q.tail = 1。因此,如果我们完全填满队列,那么 Q.tail 和 Q.head 将指向同一个位置(索引 1),上述条件不成立。我在这里想念什么?请指出我在哪里误解了文字。提前致谢。

这里 Attribute Q.head 索引或指向队列的头部。属性 Q.tail 索引新到达元素将插入队列的下一个位置。

4

7 回答 7

9

如 CLRS 中的同一段所述,

使用数组 Q[1...n] 实现最多 n-1 个元素的队列。

这意味着剩下一个位置。它用于检查队列是否已满。如果我们使用所有数组位置,空队列条件和满队列条件将是相同的,即 Q.head=Q.tail。@siddstuff 解释了环绕功能,Q.head = Q.tail+1 表示只剩下一个空位置,因此队列已满。

于 2016-07-27T16:42:15.083 回答
7

环绕队列的特征:

您需要了解数组中的位置 1 以循环顺序紧跟位置 n 的事实。例如 在此处输入图像描述

索引 1 处元素 g 的前身是索引 11 处的 f。尾指针始终指向将插入新元素的下一个空位置,在入队操作中,在插入元素之前,我们检查溢出条件,如果 Q.tail +1 = Q .head,表示在头部位置到达尾部,表示没有可用空间,表示队列已满。

注意: (n-1) 长度队列可以用长度为 n 的数组创建。

于 2013-05-06T13:05:15.933 回答
4

已经六年了,但这些答案都没有指出这样一个事实,即在循环缓冲区中,没有明确的方法来区分缓冲区满与空的情况。在这两种情况下head = tail

大多数变通方法会阻碍可读性并引入复杂性,因此在实现循环缓冲区时,我们会做出一些假设来解决这个问题并保持简单性。

  • 我们故意只使用元素缓冲区N-1中的元素。N
  • head = tail它意味着缓冲区为空时。
  • tail + 1 = head表示缓冲区已满。

这是关于实现循环缓冲区的好读物。

于 2019-05-28T03:48:35.693 回答
2

我没有你的书,但是从我将如何实现循环缓冲区:条件head = tail + 1意味着如果插入一个元素,则 tail 增加一,然后tail = head. 但是如果 head 等于 tail 则队列被认为是空的。

于 2013-05-06T10:02:38.100 回答
2

只是为了澄清,你不能让数组被完全填满的原因是因为这样就没有办法确定它是满的还是空的。

检查它是否为空Q.head = Q.tails是唯一的方法,因为您不能依赖类似Q.head = 1 and Q.tails = 1的东西,因为队列在任何位置都可能是空的,而不仅仅是位置 1。

这就是使用长度数组创建的队列n只能容纳n-1元素的原因,并且为了检查它是否已满Q.tail + 1 = Q.head(或者(Q.tail + 1) mod n考虑Q.tail点在 position的情况n)。

于 2016-06-20T17:28:25.180 回答
0

当队列用 的数组实现时Q[1..n],它最多可以容纳n-1元素。但是 for 的条件is_full必须是[head == tail+1]mod n 而不是 just head == tail+1

于 2013-12-21T07:18:03.340 回答
0

所有这些混淆都源于 CLRS 采用从 1 开始而不是 0 的数组索引这一事实。

因此,我们必须使用 n 个元素来实现容量为 n-1 的队列,因为我们有 n 个元素并且我们执行 n%n 我们将得到零,并且根据 CLRS 没有这样的索引。因此,我们限制为 n-1 容量,因此模总是至少给出 1。

于 2020-07-31T17:22:04.940 回答