这是不对排队算法的请求,我知道有很多。
我正在阅读一本C#书,它用一个代码示例解释了循环队列算法。在第13,14和15行,他解释了如何检查队列是否已满。但是我无法理解为什么第一个可选条件是必要的。有人能告诉我一个需要它的情况吗?
这是类代码:
我的问题是关于这一部分:(putloc + 1 == getloc)
public bool Put(char ch) {
/* Queue is full if either putloc is one less than
getloc, or if putloc is at the end of the array
and getloc is at the beginning. */
if (putloc + 1 == getloc || ((putloc == q.Length - 1) && (getloc == 0)))
{
return false;
}
答案 0 :(得分:6)
第一项检查是在评论中执行语句的以下部分。
putloc比getloc少一个
此检查是必需的,因为您的队列是循环的。如果您始终可以假设Queue的末尾是Array中的最后一个元素,则不需要进行检查。在这种情况下虽然......队列的结尾可能发生在数组的中间,在这种情况下,队列将满,你就会遇到这种情况。
答案 1 :(得分:2)
假设getloc是5而putloc是4,那么这意味着你没有空间放任何东西。因为如果你把东西放在5,那么你就失去了5,因为你还没读完它。
答案 2 :(得分:2)
在循环队列中,每当你向它推入一些东西时,putLoc向下移动数组,最后包裹。每当你从队列中弹出一些东西时,getLoc就会向下移动数组,也会在最后包装。当putLoc就在getLoc之前时,队列被认为是完整的。
有两种情况可能发生这种情况。如果getLoc从未移动过,或者碰巧已经回绕到数组的开头,那么当putLoc位于数组的末尾时,它就处于0并且队列已满(下一次推送将导致它换行为0)。那是if语句的下半部分。
如果从队列中弹出了几个值,则getLoc可能位于数组的 middle 中。在这种情况下,当putLoc位于数组的末尾时,队列已满,但是当它被包裹并且就在getLoc之前时。这就是if语句的第一部分(你要问的部分)正在处理。
答案 3 :(得分:1)
这两者实际上是相同的条件。从模数平等的角度来考虑它。
当添加的最新元素位于位置N(以模数长度)并且最早的元素位于位置N + 1(以模数长度)时,使用数组实现的循环队列已满。这意味着队列中有“length”元素,并且没有更多的空间用于新的元素,所以它已经满了。
有许多方法可以对该测试进行编码,但代码示例使用的方法是使用直接算术版本而不使用模数。
你也可以这样编码:
if ((putloc + 1) % q.length == getloc) {}
getloc
被正确限制在0和q.length - 1
之间,它就会在逻辑上相同。
答案 4 :(得分:1)
队列已满,如果
(((in+1)%queue_length)==out)
如果,队列是空的
(in==out)
请注意,“in”表示数据被推入队列,而“out”指向数据pop表单队列。
答案 5 :(得分:0)
通过以下形式可以更好地理解逻辑:
int new_putloc = (putloc + 1) % q.Length;
if (new_putloc == getloc) return false;
原始代码将上述逻辑分解为两种情况:
答案 6 :(得分:0)
表达式的左半部分是几乎适用于所有场景的主要部分,右半部分用于唯一边缘情况,其中putloc是队列的末尾,getloc是队列的开头。当putloc为4且getloc为5时,左侧为真,但当队列长度为10且putloc为9且getloc为0时,右侧为真。