Enhance docs, add tests in CreateAndDetectLoop (#5993)

This commit is contained in:
Hardik Pawar
2024-10-25 20:09:17 +05:30
committed by GitHub
parent c8e9e748b2
commit cd87dc3877
2 changed files with 51 additions and 23 deletions

View File

@ -1,11 +1,24 @@
package com.thealgorithms.datastructures.lists; package com.thealgorithms.datastructures.lists;
/**
* CreateAndDetectLoop provides utility methods for creating and detecting loops
* (cycles) in a singly linked list. Loops in a linked list are created by
* connecting the "next" pointer of one node to a previous node in the list,
* forming a cycle.
*/
public final class CreateAndDetectLoop { public final class CreateAndDetectLoop {
// Node class representing a single node in the linked list /**
* Private constructor to prevent instantiation of this utility class.
*/
private CreateAndDetectLoop() { private CreateAndDetectLoop() {
throw new UnsupportedOperationException("Utility class"); throw new UnsupportedOperationException("Utility class");
} }
/**
* Node represents an individual element in the linked list, containing
* data and a reference to the next node.
*/
static final class Node { static final class Node {
int data; int data;
Node next; Node next;
@ -16,19 +29,16 @@ public final class CreateAndDetectLoop {
} }
} }
// Method to create a loop between two specific positions in the linked list /**
/* * Creates a loop in a linked list by connecting the next pointer of a node
* Test case that shows the Cycle(loop) in a LinkedList * at a specified starting position (position2) to another node at a specified
* Let's take this linked list: * destination position (position1). If either position is invalid, no loop
* 1->2->3->4->5->6 * will be created.
* \______/ *
* In this linked list we can see there is a cycle. * @param head the head node of the linked list
* we can create loop by calling createLoop function in main after creating LL * @param position1 the position in the list where the loop should end
* createLoop(head,2,5); * @param position2 the position in the list where the loop should start
* to detect there is loop or not we can call detectloop function in main
* detectloop(head);
*/ */
static void createLoop(Node head, int position1, int position2) { static void createLoop(Node head, int position1, int position2) {
if (position1 == 0 || position2 == 0) { if (position1 == 0 || position2 == 0) {
return; return;
@ -39,29 +49,32 @@ public final class CreateAndDetectLoop {
int count1 = 1; int count1 = 1;
int count2 = 1; int count2 = 1;
// Traverse to find node at position1 // Traverse to the node at position1
while (count1 < position1 && node1 != null) { while (count1 < position1 && node1 != null) {
node1 = node1.next; node1 = node1.next;
count1++; count1++;
} }
// Traverse to find node at position2 // Traverse to the node at position2
while (count2 < position2 && node2 != null) { while (count2 < position2 && node2 != null) {
node2 = node2.next; node2 = node2.next;
count2++; count2++;
} }
// Create a loop by connecting node2's next to node1 // If both nodes are valid, create the loop
if (node1 != null && node2 != null) { if (node1 != null && node2 != null) {
node2.next = node1; node2.next = node1;
} }
} }
// Method to detect a loop in the linked list
/** /**
* Detects the presence of a loop in the linked list. * Detects the presence of a loop in the linked list using Floyd's cycle-finding
* algorithm, also known as the "tortoise and hare" method.
* *
* @see <a href="https://en.wikipedia.org/wiki/Cycle_detection#Floyd's_tortoise_and_hare">Floyd's Cycle Detection Algorithm</a> * @param head the head node of the linked list
* @return true if loop exists else false * @return true if a loop is detected, false otherwise
* @see <a href="https://en.wikipedia.org/wiki/Cycle_detection#Floyd's_tortoise_and_hare">
* Floyd's Cycle Detection Algorithm</a>
*/ */
static boolean detectLoop(Node head) { static boolean detectLoop(Node head) {
Node sptr = head; Node sptr = head;

View File

@ -12,7 +12,7 @@ public class CreateAndDetectLoopTest {
@BeforeEach @BeforeEach
void setUp() { void setUp() {
// Create a linked list: 1 -> 2 -> 3 -> 4 -> 5 -> 6 // Set up a linked list: 1 -> 2 -> 3 -> 4 -> 5 -> 6
head = new CreateAndDetectLoop.Node(1); head = new CreateAndDetectLoop.Node(1);
CreateAndDetectLoop.Node second = new CreateAndDetectLoop.Node(2); CreateAndDetectLoop.Node second = new CreateAndDetectLoop.Node(2);
CreateAndDetectLoop.Node third = new CreateAndDetectLoop.Node(3); CreateAndDetectLoop.Node third = new CreateAndDetectLoop.Node(3);
@ -44,7 +44,7 @@ public class CreateAndDetectLoopTest {
@Test @Test
void testCreateLoopInvalidPosition() { void testCreateLoopInvalidPosition() {
// Create loop with invalid positions // Create loop with invalid positions (0)
CreateAndDetectLoop.createLoop(head, 0, 0); CreateAndDetectLoop.createLoop(head, 0, 0);
// Ensure no loop was created // Ensure no loop was created
@ -62,10 +62,25 @@ public class CreateAndDetectLoopTest {
@Test @Test
void testCreateLoopNoChangeForNonExistentPositions() { void testCreateLoopNoChangeForNonExistentPositions() {
// Create a loop with positions that don't exist in the linked list // Create a loop with non-existent positions
CreateAndDetectLoop.createLoop(head, 10, 20); CreateAndDetectLoop.createLoop(head, 10, 20);
// Ensure no loop was created // Ensure no loop was created
assertFalse(CreateAndDetectLoop.detectLoop(head), "No loop should be created if positions are out of bounds."); assertFalse(CreateAndDetectLoop.detectLoop(head), "No loop should be created if positions are out of bounds.");
} }
@Test
void testMultipleNodesWithNoLoop() {
// Multiple nodes without creating any loop
assertFalse(CreateAndDetectLoop.detectLoop(head), "No loop should be detected for a standard linear list.");
}
@Test
void testHeadToTailLoop() {
// Create a loop from the tail back to the head
CreateAndDetectLoop.createLoop(head, 1, 6);
// Detect the head-to-tail loop
assertTrue(CreateAndDetectLoop.detectLoop(head), "A head-to-tail loop should be detected.");
}
} }