【问题标题】:My concern about getting rid of loop from single link list我担心从单链表中摆脱循环
【发布时间】:2013-05-02 04:38:30
【问题描述】:

我知道这是一个常见问题解答,并且有很多答案,例如 Interview: Remove Loop in linked list - Java。但我有以下担忧。如果我错了,请指出,你能指导我到一个正确答案的链接吗?

  1. 如果既要检测又要消除循环,应将if (fast_ptr==slow_ptr || fast_ptr->_next == slow_ptr)更改为if (fast_ptr==slow_ptr);因为只有一个入口点。
  2. 入口时应考虑头部情况。即案例:1->2->3->4->1->2->3->4...,我从来没有看到任何链接显示这种情况。我错了吗?

这是我的代码:

bool determine_remove_Cycle_list(sIntElement *head){     
    sIntElement* slow_ptr = head;    
    sIntElement* fast_ptr = head;     
    while(true){    
        if (!fast_ptr || !(fast_ptr->_next)) return false;     
        slow_ptr = slow_ptr->_next;    
        fast_ptr = fast_ptr->_next->_next;    
        if (fast_ptr==slow_ptr)//fast_ptr->_next == slow_ptr is not checked
            break; //is cycle
        }
        fast_ptr = head;    
        while(fast_ptr->_next != slow_ptr->_next){    
            fast_ptr = fast_ptr->_next;    
            slow_ptr = slow_ptr->_next;    
        }    
     }
     if (slow_ptr == head){ //special case: start of the cycle is head,    
            while (slow_ptr->_next != head){    
            slow_ptr = slow_ptr->_next;    
     }    

     slow_ptr->_next = NULL; //slow is the node before the start point
     return true;    
}

【问题讨论】:

  • 这是 C,不是 Java,不是吗?
  • 应该标记为 C.:)

标签: c algorithm


【解决方案1】:

从slowptr = head 开始,fastptr = head->next。在更新 slowptr 和 fastptr 之前进行两次比较。

您不想删除支票,正如您在 1) 中所说的那样。当 (fastptr == slowptr || fastptr->next == slowptr) 时,如您所知,您有循环。删除循环只是将指向 slowptr 的任何一个更改为指向 null 的问题。 (tail->next == head) 不需要特殊情况——试试吧。

第二个循环是多余的,永远不会中断。

重申(不是双关语),打破循环,你改变

【讨论】:

  • 嗨,本,谢谢您的回答。我刚刚更新了我原来的帖子,因为我发现代码与我测试的有点不同。
  • 嗨,本,感谢您的回答。我刚刚更新了我的原始帖子,因为我发现代码与我测试的有点不同。我还根据您的意思发布了代码(见下文):1)fastptr = head->next。 2)检查 fastptr->next == slowptr 以及。 3) 删除检查tail->next=hd 的特殊情况的代码。但是我发现在这种情况下,slow ptr 最终会在 3 处停止(step of slow:1,2,3, fast=2,4,2)所以通过打破slow->next=null,链接列表变为:hd= 1->2->3->null,不是1->2->3->4->null,4是遗漏的;而 w。上面的代码,循环在 4:1->2->3->4->null 之后中断。
【解决方案2】:
bool determine_remove_Cycle_list_2(sIntElement *head){ 
    sIntElement* slow_ptr = head;
    if (!head) return false;
    sIntElement* fast_ptr = head->_next; 
    while(true){
       if (!fast_ptr || !(fast_ptr->_next)) return false; 
       if (fast_ptr==slow_ptr || fast_ptr->_next == slow_ptr)
            break; //find the cycle
       else {
        slow_ptr = slow_ptr->_next;
        fast_ptr = fast_ptr->_next->_next;
       }
    }  
//slow is at position p here.
    fast_ptr = head;

    while(fast_ptr->_next != slow_ptr->_next){
    fast_ptr = fast_ptr->_next;
    slow_ptr = slow_ptr->_next;
    }

    slow_ptr->_next = NULL; 
    return true;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-02
    • 1970-01-01
    • 2013-06-20
    • 1970-01-01
    • 2014-09-05
    相关资源
    最近更新 更多