在双向链表中循环

Jon*_*ony 5 linked-list

如何在双向链表中找到循环?如何消除循环?

Anu*_*arg 1

将其视为单链表并执行以下操作。

int detectloop(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 == fast_p)
    {
       printf("Found Loop");
       return 1;
    }
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我们使用了两个指针,一个是慢速,另一个是快速,慢速移动一步,快速移动两步。当它们都相遇时,我们可以说链表有循环,否则没有。

void removeLoop(struct node *loop_node, struct node *head)
{
   struct node *ptr1;
   struct node *ptr2;

   /* Set a pointer to the beging of the Linked List and
      move it one by one to find the first node which is
      part of the Linked List */
   ptr1 = head;
   while(1)
   {
     /* Now start a pointer from loop_node and check if it ever
       reaches ptr2 */
     ptr2 = loop_node;
     while(ptr2->next != loop_node && ptr2->next != ptr1)
     {
         ptr2 = ptr2->next;
     }

     /* If ptr2 reahced ptr1 then there is a loop. So break the
        loop */
     if(ptr2->next == ptr1)
        break;

     /* If ptr2 did't reach ptr1 then try the next node after ptr1 */
     else
       ptr1 = ptr1->next;
   }

   /* After the end of loop ptr2 is the last node of the loop. So
     make next of ptr2 as NULL */
   ptr2->next = NULL;
}
Run Code Online (Sandbox Code Playgroud)

检测到循环后,我们可以使用一个循环并从头开始,并以通常的速度移动慢速指针,当两个指针相遇时,就是循环的开始,我们可以打破它。