📜  在链表中查找循环的长度

📅  最后修改于: 2022-05-13 01:57:43.487000             🧑  作者: Mango

在链表中查找循环的长度

编写一个函数detectAndCountLoop()来检查给定的链表是否包含循环,如果存在循环,则返回循环中节点的计数。例如,循环存在于下链表中,循环长度为 4。如果不存在循环,则函数应返回 0。

方法众所周知,当快慢指针在公共点相遇时,弗洛伊德循环检测算法终止。众所周知,该公共点是循环节点之一。将这个公共点的地址存储在一个指针变量中,比如 (ptr)。然后用 1 初始化计数器并从公共点开始,继续访问下一个节点并增加计数器,直到再次到达公共指针。
此时,计数器的值将等于循环的长度。
算法:

  1. 使用 Floyd's Cycle 检测算法找到循环中的公共点
  2. 将指针存储在临时变量中并保持计数 = 0
  3. 遍历链表直到再次到达同一节点并在移动到下一个节点时增加计数。
  4. 将计数打印为循环长度



C++
// C++ program to count number of nodes
// in loop in a linked list if loop is
// present
#include
using namespace std;
 
/* Link list node */
struct Node
{
    int data;
    struct Node* next;
};
 
// Returns count of nodes present in loop.
int countNodes(struct Node *n)
{
    int res = 1;
    struct Node *temp = n;
    while (temp->next != n)
    {
        res++;
        temp = temp->next;
    }
    return res;
}
 
/* This function detects and counts loop
nodes in the list. If loop is not there
in then returns 0 */
int countNodesinLoop(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)
            return countNodes(slow_p);
    }
 
    /* Return 0 to indeciate that
       their is no loop*/
    return 0;
}
 
struct Node *newNode(int key)
{
    struct Node *temp =
   (struct Node*)malloc(sizeof(struct Node));
    temp->data = key;
    temp->next = NULL;
    return temp;
}
 
// Driver Code
int main()
{
    struct Node *head = newNode(1);
    head->next = newNode(2);
    head->next->next = newNode(3);
    head->next->next->next = newNode(4);
    head->next->next->next->next = newNode(5);
 
    /* Create a loop for testing */
    head->next->next->next->next->next = head->next;
 
    cout << countNodesinLoop(head) << endl;
 
    return 0;
}
 
// This code is contributed by SHUBHAMSINGH10


C
// C program to count number of nodes
// in loop in a linked list if loop is
// present
#include
#include
 
/* Link list node */
struct Node
{
    int data;
    struct Node* next;
};
 
// Returns count of nodes present in loop.
int countNodes(struct Node *n)
{
   int res = 1;
   struct Node *temp = n;
   while (temp->next != n)
   {
      res++;
      temp = temp->next;
   }
   return res;
}
 
/* This function detects and counts loop
   nodes in the list. If loop is not there
   in then returns 0 */
int countNodesinLoop(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)
            return countNodes(slow_p);
    }
 
    /* Return 0 to indeciate that ther is no loop*/
    return 0;
}
 
struct Node *newNode(int key)
{
    struct Node *temp =
        (struct Node*)malloc(sizeof(struct Node));
    temp->data = key;
    temp->next = NULL;
    return temp;
}
 
/* Driver program to test above function*/
int main()
{
    struct Node *head = newNode(1);
    head->next = newNode(2);
    head->next->next = newNode(3);
    head->next->next->next = newNode(4);
    head->next->next->next->next = newNode(5);
 
    /* Create a loop for testing */
    head->next->next->next->next->next = head->next;
 
    printf("%d \n", countNodesinLoop(head));
 
    return 0;
}


Java
// Java program to count number of nodes
// in loop in a linked list if loop is
// present
import java.io.*;
 
class GFG {
     
 
/* Link list node */
static class Node
{
    int data;
    Node next;
    Node(int data)
    {
        this.data =data;
        next =null;
    }
}
 
// Returns count of nodes present in loop.
static int countNodes( Node n)
{
int res = 1;
Node temp = n;
while (temp.next != n)
{
    res++;
    temp = temp.next;
}
return res;
}
 
/* This function detects and counts loop
nodes in the list. If loop is not there
in then returns 0 */
static int countNodesinLoop( Node list)
{
    Node slow_p = list, fast_p = list;
 
    while (slow_p !=null && fast_p!=null && fast_p.next!=null)
    {
        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)
            return countNodes(slow_p);
    }
 
    /* Return 0 to indeciate that ther is no loop*/
    return 0;
}
 
static Node newNode(int key)
{
    Node temp = new Node(key);
     
    return temp;
}
 
/* Driver program to test above function*/
    public static void main (String[] args) {
        Node head = newNode(1);
    head.next = newNode(2);
    head.next.next = newNode(3);
    head.next.next.next = newNode(4);
    head.next.next.next.next = newNode(5);
 
    /* Create a loop for testing */
    head.next.next.next.next.next = head.next;
 
    System.out.println( countNodesinLoop(head));
    }
}
// This code is contributed by inder_verma.


Python3
# Python 3 program to find the number
# of nodes in looop in a linked list
# if loop is present
 
# Python Code to detect a loop and
# find the length of the loop
# Node defining class
class Node:
     
    # Function to make a node
    def __init__(self, val):
        self.val = val
        self.next = None
     
# Linked List defining and loop
# length finding class
class LinkedList:
     
    # Function to initialize the
    # head of the linked list
    def __init__(self):
        self.head = None       
         
    # Function to insert a new
    # node at the end
    def AddNode(self, val):
        if self.head is None:
            self.head = Node(val)
        else:
            curr = self.head
            while(curr.next):
                curr = curr.next
            curr.next = Node(val)
     
    # Function to create a loop in the
    # Linked List. This function creates
    # a loop by connnecting the last node
    # to n^th node of the linked list,
    # (counting first node as 1)
    def CreateLoop(self, n):
         
        # LoopNode is the connecting node to
        # the last node of linked list
        LoopNode = self.head
        for _ in range(1, n):
            LoopNode = LoopNode.next
             
        # end is the last node of the Linked List
        end = self.head
        while(end.next):
            end = end.next
             
        # Creating the loop
        end.next = LoopNode
         
    # Function to detect the loop and return
    # the length of the loop if the returned
    # value is zero, that means that either
    # the linked list is empty or the linked
    # list doesn't have any loop
    def detectLoop(self):
         
        # if linked list is empty then there
        # is no loop, so return 0
        if self.head is None:
            return 0
         
        # Using Floyd’s Cycle-Finding
        # Algorithm/ Slow-Fast Pointer Method
        slow = self.head
        fast = self.head
        flag = 0 # to show that both slow and fast
                 # are at start of the Linked List
        while(slow and slow.next and fast and
              fast.next and fast.next.next):
            if slow == fast and flag != 0:
                 
                # Means loop is confirmed in the
                # Linked List. Now slow and fast
                # are both at the same node which
                # is part of the loop
                count = 1
                slow = slow.next
                while(slow != fast):
                    slow = slow.next
                    count += 1
                return count
             
            slow = slow.next
            fast = fast.next.next
            flag = 1
        return 0 # No loop
     
# Setting up the code
# Making a Linked List and adding the nodes
myLL = LinkedList()
myLL.AddNode(1)
myLL.AddNode(2)
myLL.AddNode(3)
myLL.AddNode(4)
myLL.AddNode(5)
 
# Creating a loop in the linked List
# Loop is created by connecting the
# last node of linked list to n^th node
# 1<= n <= len(LinkedList)
myLL.CreateLoop(2)
 
# Checking for Loop in the Linked List
# and printing the length of the loop
loopLength = myLL.detectLoop()
if myLL.head is None:
    print("Linked list is empty")
else:
    print(str(loopLength))
 
# This code is contributed by _Ashutosh


C#
// C# program to count number of nodes
// in loop in a linked list if loop is
// present
using System;
 
class GFG
{
 
    /* Link list node */
    class Node
    {
        public int data;
        public Node next;
        public Node(int data)
        {
            this.data = data;
            next = null;
        }
    }
 
    // Returns count of nodes present in loop.
    static int countNodes( Node n)
    {
        int res = 1;
        Node temp = n;
        while (temp.next != n)
        {
            res++;
            temp = temp.next;
        }
        return res;
    }
 
    /* This function detects and counts loop
    nodes in the list. If loop is not there
    in then returns 0 */
    static int countNodesinLoop( Node list)
    {
        Node slow_p = list, fast_p = list;
 
        while (slow_p != null && fast_p != null &&
                            fast_p.next != null)
        {
            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)
                return countNodes(slow_p);
        }
 
        /* Return 0 to indeciate that ther is no loop*/
        return 0;
    }
 
    static Node newNode(int key)
    {
        Node temp = new Node(key);
 
        return temp;
    }
 
    /* Driver code*/
    public static void Main (String[] args)
    {
        Node head = newNode(1);
        head.next = newNode(2);
        head.next.next = newNode(3);
        head.next.next.next = newNode(4);
        head.next.next.next.next = newNode(5);
 
        /* Create a loop for testing */
        head.next.next.next.next.next = head.next;
 
        Console.WriteLine( countNodesinLoop(head));
    }
}
 
// This code is contributed by Rajput-Ji


Javascript


输出 :

4

复杂度分析:

  • 时间复杂度: O(n)。
    只需要对链表进行一次遍历。
  • 辅助空间: O(1)。
    因为不需要额外的空间。

相关文章:

  • 检测链表中的循环
  • 检测和删除链表中的循环

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程