C 对求循环表算法的质疑
我用C编写了以下代码,试图找出列表是否是循环的:C 对求循环表算法的质疑,c,linked-list,C,Linked List,我用C编写了以下代码,试图找出列表是否是循环的: bool findCircular(Node *head) { Node *slower, * faster; slower = head; faster = head; while(true) { // if the faster pointer encounters a NULL element if( !faster || !faster->next) return fals
bool findCircular(Node *head)
{
Node *slower, * faster;
slower = head;
faster = head;
while(true) {
// if the faster pointer encounters a NULL element
if( !faster || !faster->next)
return false;
//if faster pointer ever equals slower or faster's next
//pointer is ever equal to slow then it's a circular list
else if (faster == slower || faster->next == slower)
return true;
else{
// advance the pointers
slower = slower->next;
faster = faster->next->next;
}
}
}
我对它的某些部分有一些问题。首先,在我们第一次进入while循环时,我们不是总是要达到这个条件(更快=更慢)?我们以更快和更慢的速度初始化,以指向它指向头部的相同位置
第二,为什么我们还要比较如果(更快->下一步==更慢),我们仅仅
更快==更慢
,还不够吗?不要从头部开始更快
和更慢
。执行错误检查并从head->next
启动更快的
如果没有faster->next==sleer
算法应该可以工作。实际上,书中打印的代码是不正确的,并且将返回1,除非传递了null或1元素列表。显示的是一个已更正的版本
修复方法是跟踪这是否是第一次通过循环,并从第二次开始执行循环列表检查,通过:
int first = 1; /* New code */
while (1) {
if (!faster || !faster->next)
return 0;
else if ((faster == slower || faster->next == slower) && !first) /* New code */
return 1;
else {
slower = slower->next;
faster = faster->next->next;
first = 0; /* New code */
}
}
(上面的代码使用“快”和“慢”,就像在你的版本中一样;书和勘误表使用“快”和“慢”。它能工作吗?看起来您需要删除faster==sleer | |
您的问题只是“这个算法是如何工作的”吗?不,WhozCraig是关于为什么实现是这样的。我从《编程访谈》一书中复制了它,但我不明白为什么会这样实现。@HommerSmith,这是错误的。正确的算法首先推进快速指针和尾部指针(快速指针两次),然后检查列表末尾(fast | fast->next为NULL)或(fast | fast->next)是否与slow相等,如果两者相等则中断。因此,如果你的问题是这本书是否正确,那就不是了。如果你想要正确的算法,我会发布。WhozCraig,你能用C发布正确的算法吗?