我正在尝试理解为检测和删除链接列表中的循环而编写的C代码(取自here)。尽管其他一切对我来说都很有意义,但我无法理解while
语句中发生的事情。更具体地说,将逻辑AND应用于指针结构时会如何表现?
while (slow_p && fast_p && fast_p->next)
这里采用了野兔和乌龟的方法,其中我们使用两个指针,一个是快指针,另一个是慢指针。
/* Link list node */
struct Node
{
int data;
struct Node* next;
};
/* Function to remove loop. Used by detectAndRemoveLoop() */
void removeLoop(struct Node *, struct Node *);
/* This function detects and removes loop in the list
If loop was there in the list then it returns 1,
otherwise returns 0 */
int detectAndRemoveLoop(struct Node *list)
{
struct Node *slow_p = list, *fast_p = list;
while (slow_p && fast_p && fast_p->next)
{
slow_p = slow_p->next;
fast_p = fast_p->next->next;
/* If slow_p and fast_p meet at some point then there
is a loop */
if (slow_p == fast_p)
{
removeLoop(slow_p, list);
/* Return 1 to indicate that loop is found */
return 1;
}
}
/* Return 0 to indeciate that ther is no loop*/
return 0;
}
答案 0 :(得分:4)
您所拥有的条件是,如果三个指针之一为NULL
,则确保循环中断并退出。空指针始终在C中的值为布尔值false
。请参见https://en.wikipedia.org/wiki/Null_pointer#Null_pointer。
但是,使用当前逻辑,如果列表中存在循环,则很可能没有指针为NULL,因为我们检测到了循环并中断了循环。仅当列表中没有循环并且您刚刚遍历整个列表以尝试找到一个列表时,fast_p
指针才可能是NULL
。
执行顺序如下
slow_p
将在节点2上,fast_p
将在节点3上slow_p
将在节点3上,fast_p
将在节点5上slow_p
将在节点4处,fast_p
将经过循环节点并再次在节点3处slow_p
将位于节点5,fast_p
将位于节点5 这时,这两个指针都指向同一地址的节点,因此地址比较将断言,导致函数中断并返回slow_p
的地址,该地址现在精确地为 指向导致此循环循环的节点。