mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-07-06 00:54:32 +08:00
Enhance docs, add tests in CreateAndDetectLoop
(#5993)
This commit is contained in:
@ -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;
|
||||||
|
@ -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.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user