diff --git a/src/main/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoop.java b/src/main/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoop.java index 441c95702050..49115b2d0f3d 100644 --- a/src/main/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoop.java +++ b/src/main/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoop.java @@ -1,63 +1,66 @@ package com.thealgorithms.datastructures.lists; -import java.util.Scanner; - public final class CreateAndDetectLoop { + + // Node class representing a single node in the linked list private CreateAndDetectLoop() { + throw new UnsupportedOperationException("Utility class"); } + static final class Node { + int data; + Node next; - /** - * Prints the linked list. - * - * @param head head node of the linked list - */ - static void printList(Node head) { - Node cur = head; - - while (cur != null) { - System.out.print(cur.value + " "); - cur = cur.next; + Node(int data) { + this.data = data; + next = null; } } - /** - * Creates a loop in the linked list. - * - * @see - * - * GeeksForGeeks: Make a loop at K-th position - * @param head head node of the linked list - * @param k position of node where loop is to be created + // Method to create a loop between two specific positions in the linked list + /* + * Test case that shows the Cycle(loop) in a LinkedList + * Let's take this linked list: + * 1->2->3->4->5->6 + * \______/ + * In this linked list we can see there is a cycle. + * we can create loop by calling createLoop function in main after creating LL + * createLoop(head,2,5); + * to detect there is loop or not we can call detectloop function in main + * detectloop(head); */ - static void createLoop(Node head, int k) { - if (head == null) { + + static void createLoop(Node head, int position1, int position2) { + if (position1 == 0 || position2 == 0) { return; } - Node temp = head; - int count = 1; - while (count < k) { // Traverse the list till the kth node - temp = temp.next; - count++; - } - Node connectedPoint = temp; + Node node1 = head; + Node node2 = head; - while (temp.next != null) { // Traverse remaining nodes - temp = temp.next; + int count1 = 1; + int count2 = 1; + // Traverse to find node at position1 + while (count1 < position1 && node1 != null) { + node1 = node1.next; + count1++; } - temp.next = connectedPoint; // Connect last node to k-th element - } + // Traverse to find node at position2 + while (count2 < position2 && node2 != null) { + node2 = node2.next; + count2++; + } + // Create a loop by connecting node2's next to node1 + if (node1 != null && node2 != null) { + node2.next = node1; + } + } + // Method to detect a loop in the linked list /** * Detects the presence of a loop in the linked list. * - * @see - * - * Floyd's Cycle Detection Algorithm - * - * @param head the head node of the linked list - * + * @see Floyd's Cycle Detection Algorithm * @return true if loop exists else false */ static boolean detectLoop(Node head) { @@ -67,40 +70,10 @@ static boolean detectLoop(Node head) { while (fptr != null && fptr.next != null) { sptr = sptr.next; fptr = fptr.next.next; - if (fptr == sptr) { + if (sptr == fptr) { return true; } } - return false; } - - public static void main(String[] args) { - SinglyLinkedList singlyLinkedList = new SinglyLinkedList(); - Scanner sc = new Scanner(System.in); - - System.out.println("Enter the number of elements to be inserted: "); - int n = sc.nextInt(); - System.out.printf("Enter the %d elements: %n", n); - while (n-- > 0) { - singlyLinkedList.insert(sc.nextInt()); - } - - System.out.print("Given list: "); - printList(singlyLinkedList.getHead()); - System.out.println(); - - System.out.println("Enter the location to generate loop: "); - int k = sc.nextInt(); - - createLoop(singlyLinkedList.getHead(), k); - - if (detectLoop(singlyLinkedList.getHead())) { - System.out.println("Loop found"); - } else { - System.out.println("No loop found"); - } - - sc.close(); - } } diff --git a/src/test/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoopTest.java b/src/test/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoopTest.java new file mode 100644 index 000000000000..5e9d4c3a2913 --- /dev/null +++ b/src/test/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoopTest.java @@ -0,0 +1,71 @@ +package com.thealgorithms.datastructures.lists; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class CreateAndDetectLoopTest { + + private CreateAndDetectLoop.Node head; + + @BeforeEach + void setUp() { + // Create a linked list: 1 -> 2 -> 3 -> 4 -> 5 -> 6 + head = new CreateAndDetectLoop.Node(1); + CreateAndDetectLoop.Node second = new CreateAndDetectLoop.Node(2); + CreateAndDetectLoop.Node third = new CreateAndDetectLoop.Node(3); + CreateAndDetectLoop.Node fourth = new CreateAndDetectLoop.Node(4); + CreateAndDetectLoop.Node fifth = new CreateAndDetectLoop.Node(5); + CreateAndDetectLoop.Node sixth = new CreateAndDetectLoop.Node(6); + + head.next = second; + second.next = third; + third.next = fourth; + fourth.next = fifth; + fifth.next = sixth; + } + + @Test + void testDetectLoopNoLoop() { + // Test when no loop exists + assertFalse(CreateAndDetectLoop.detectLoop(head), "There should be no loop."); + } + + @Test + void testCreateAndDetectLoopLoopExists() { + // Create a loop between position 2 (node with value 2) and position 5 (node with value 5) + CreateAndDetectLoop.createLoop(head, 2, 5); + + // Now test if the loop is detected + assertTrue(CreateAndDetectLoop.detectLoop(head), "A loop should be detected."); + } + + @Test + void testCreateLoopInvalidPosition() { + // Create loop with invalid positions + CreateAndDetectLoop.createLoop(head, 0, 0); + + // Ensure no loop was created + assertFalse(CreateAndDetectLoop.detectLoop(head), "There should be no loop with invalid positions."); + } + + @Test + void testCreateLoopSelfLoop() { + // Create a self-loop at position 3 (node with value 3) + CreateAndDetectLoop.createLoop(head, 3, 3); + + // Test if the self-loop is detected + assertTrue(CreateAndDetectLoop.detectLoop(head), "A self-loop should be detected."); + } + + @Test + void testCreateLoopNoChangeForNonExistentPositions() { + // Create a loop with positions that don't exist in the linked list + CreateAndDetectLoop.createLoop(head, 10, 20); + + // Ensure no loop was created + assertFalse(CreateAndDetectLoop.detectLoop(head), "No loop should be created if positions are out of bounds."); + } +}