链表具有循环功能检查

时间:2019-02-17 14:38:43

标签: c linked-list

我编写了一个代码来检查链表输入是否有循环,但是我的方法与Internet上的方法有些不同,这行得通吗?

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
bool hasCycle(struct ListNode *head) {
    struct ListNode *p1,*p2;
    p1 = head;
    if(p1 == NULL) return 0;
    for(p1 = head;p1->next != NULL;p1 = p1->next){
        for(p2 = p1->next;p2 != NULL;p2=p2->next){
            if(p2 == p1) return 1;
            if (p2 == NULL) return 0;
        }
    }
    return 0;

}

1 个答案:

答案 0 :(得分:0)

您回来太早了:

    for(p2 = p1->next;p2 != NULL;p2=p2->next){
        if(p2 == p1) return 1;
        if (p2 == NULL) return 0;
    }

p2变为NULL时,仅表示没有循环涉及p1 ,根本没有任何循环。通过在此处返回0,您只需检查头节点是否存在一个循环。

摆脱多余的回报,所以搜索完所有内容后,您只会返回0。

for(p1 = head;p1->next != NULL;p1 = p1->next){
    for(p2 = p1->next;p2 != NULL;p2=p2->next){
        if(p2 == p1) return 1;
    }
}
return 0;

编辑:

这仍然不起作用,因为如果循环不涉及第一个节点,它将进入无限循环。处理此问题的正确方法是对照找到的所有先前节点检查每个节点。这可以通过在访问节点时将其放入列表中来完成。如果在添加列表之前该列表中已经存在一个节点,则您发现了一个循环。

或者,您可以在初始化为0的每个节点中放置一个“ visited”标志。然后遍历设置该标志的列表。如果该标志已经设置,则您有一个循环。