Skip to content

updated CreateAndDetectLoop with test #5561

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 13 commits into from
Oct 9, 2024
Original file line number Diff line number Diff line change
@@ -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
* <a href="https://www.geeksforgeeks.org/make-loop-k-th-position-linked-list/">
* GeeksForGeeks: Make a loop at K-th position</a>
* @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
* <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
*
* @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
*/
static boolean detectLoop(Node head) {
Expand All @@ -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();
}
}
Original file line number Diff line number Diff line change
@@ -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.");
}
}