Skip to content

refactor: Enhance docs, add tests in CreateAndDetectLoop #5993

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
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 {

// Node class representing a single node in the linked list
/**
* Private constructor to prevent instantiation of this utility class.
*/
private CreateAndDetectLoop() {
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 {
int data;
Node next;
Expand All @@ -16,19 +29,16 @@ static final class Node {
}
}

// 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);
/**
* Creates a loop in a linked list by connecting the next pointer of a node
* at a specified starting position (position2) to another node at a specified
* destination position (position1). If either position is invalid, no loop
* will be created.
*
* @param head the head node of the linked list
* @param position1 the position in the list where the loop should end
* @param position2 the position in the list where the loop should start
*/

static void createLoop(Node head, int position1, int position2) {
if (position1 == 0 || position2 == 0) {
return;
Expand All @@ -39,29 +49,32 @@ static void createLoop(Node head, int position1, int position2) {

int count1 = 1;
int count2 = 1;
// Traverse to find node at position1
// Traverse to the node at position1
while (count1 < position1 && node1 != null) {
node1 = node1.next;
count1++;
}

// Traverse to find node at position2
// Traverse to the node at position2
while (count2 < position2 && node2 != null) {
node2 = node2.next;
count2++;
}

// Create a loop by connecting node2's next to node1
// If both nodes are valid, create the loop
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.
* 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>
* @return true if loop exists else false
* @param head the head node of the linked list
* @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) {
Node sptr = head;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class CreateAndDetectLoopTest {

@BeforeEach
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);
CreateAndDetectLoop.Node second = new CreateAndDetectLoop.Node(2);
CreateAndDetectLoop.Node third = new CreateAndDetectLoop.Node(3);
Expand Down Expand Up @@ -44,7 +44,7 @@ void testCreateAndDetectLoopLoopExists() {

@Test
void testCreateLoopInvalidPosition() {
// Create loop with invalid positions
// Create loop with invalid positions (0)
CreateAndDetectLoop.createLoop(head, 0, 0);

// Ensure no loop was created
Expand All @@ -62,10 +62,25 @@ void testCreateLoopSelfLoop() {

@Test
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);

// Ensure no loop was created
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.");
}
}