BAEL 1123 - deep20jain@gmail.com (#2572)
* Adding node and cycle detection by hashing * Adding implementation for all algorithms for cycle detection and removal * Applying formatting rules * Refactoring methods and adding more tests * Fixing infinite loop corner case
This commit is contained in:
committed by
Zeger Hendrikse
parent
35ac22c947
commit
cccd6a3eab
@@ -2,19 +2,22 @@ package com.baeldung.algorithms.linkedlist;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
@RunWith(value = Parameterized.class)
|
||||
public class CycleDetectionBruteForceTest extends CycleDetectionTestBase {
|
||||
boolean cycleExists;
|
||||
Node<Integer> head;
|
||||
|
||||
@Test
|
||||
public void givenNormalList_dontDetectLoop() {
|
||||
Node<Integer> root = createList();
|
||||
Assert.assertFalse(CycleDetectionBruteForce.detectCycle(root));
|
||||
public CycleDetectionBruteForceTest(Node<Integer> head, boolean cycleExists) {
|
||||
super();
|
||||
this.cycleExists = cycleExists;
|
||||
this.head = head;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCyclicList_detectLoop() {
|
||||
Node<Integer> root = createList();
|
||||
createLoop(root);
|
||||
Assert.assertTrue(CycleDetectionBruteForce.detectCycle(root));
|
||||
public void givenList_detectLoop() {
|
||||
Assert.assertEquals(cycleExists, CycleDetectionBruteForce.detectCycle(head).cycleExists);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,19 +2,22 @@ package com.baeldung.algorithms.linkedlist;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
@RunWith(value = Parameterized.class)
|
||||
public class CycleDetectionByFastAndSlowIteratorsTest extends CycleDetectionTestBase {
|
||||
boolean cycleExists;
|
||||
Node<Integer> head;
|
||||
|
||||
@Test
|
||||
public void givenNormalList_dontDetectLoop() {
|
||||
Node<Integer> root = createList();
|
||||
Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(root));
|
||||
public CycleDetectionByFastAndSlowIteratorsTest(Node<Integer> head, boolean cycleExists) {
|
||||
super();
|
||||
this.cycleExists = cycleExists;
|
||||
this.head = head;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCyclicList_detectLoop() {
|
||||
Node<Integer> root = createList();
|
||||
createLoop(root);
|
||||
Assert.assertTrue(CycleDetectionByFastAndSlowIterators.detectCycle(root));
|
||||
public void givenList_detectLoop() {
|
||||
Assert.assertEquals(cycleExists, CycleDetectionByFastAndSlowIterators.detectCycle(head).cycleExists);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,19 +2,22 @@ package com.baeldung.algorithms.linkedlist;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
@RunWith(value = Parameterized.class)
|
||||
public class CycleDetectionByHashingTest extends CycleDetectionTestBase {
|
||||
boolean cycleExists;
|
||||
Node<Integer> head;
|
||||
|
||||
@Test
|
||||
public void givenNormalList_dontDetectLoop() {
|
||||
Node<Integer> root = createList();
|
||||
Assert.assertFalse(CycleDetectionByHashing.detectCycle(root));
|
||||
public CycleDetectionByHashingTest(Node<Integer> head, boolean cycleExists) {
|
||||
super();
|
||||
this.cycleExists = cycleExists;
|
||||
this.head = head;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCyclicList_detectLoop() {
|
||||
Node<Integer> root = createList();
|
||||
createLoop(root);
|
||||
Assert.assertTrue(CycleDetectionByHashing.detectCycle(root));
|
||||
public void givenList_detectLoop() {
|
||||
Assert.assertEquals(cycleExists, CycleDetectionByHashing.detectCycle(head).cycleExists);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,22 @@
|
||||
package com.baeldung.algorithms.linkedlist;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
public class CycleDetectionTestBase {
|
||||
|
||||
@Parameters
|
||||
public static Collection<Object[]> getLists() {
|
||||
return Arrays.asList(new Object[][] {
|
||||
{ createList(), false },
|
||||
{ createListWithLoop(), true },
|
||||
{ createListWithFullCycle(), true },
|
||||
{ createListWithSingleNodeInCycle(), true }
|
||||
});
|
||||
}
|
||||
|
||||
public static Node<Integer> createList() {
|
||||
Node<Integer> root = Node.createNewNode(10, null);
|
||||
|
||||
@@ -13,6 +28,26 @@ public class CycleDetectionTestBase {
|
||||
return root;
|
||||
}
|
||||
|
||||
public static Node<Integer> createListWithLoop() {
|
||||
Node<Integer> node = createList();
|
||||
createLoop(node);
|
||||
return node;
|
||||
}
|
||||
|
||||
public static Node<Integer> createListWithFullCycle() {
|
||||
Node<Integer> head = createList();
|
||||
Node<Integer> tail = Node.getTail(head);
|
||||
tail.next = head;
|
||||
return head;
|
||||
}
|
||||
|
||||
public static Node<Integer> createListWithSingleNodeInCycle() {
|
||||
Node<Integer> head = createList();
|
||||
Node<Integer> tail = Node.getTail(head);
|
||||
tail.next = tail;
|
||||
return head;
|
||||
}
|
||||
|
||||
public static void createLoop(Node<Integer> root) {
|
||||
Node<Integer> tail = Node.getTail(root);
|
||||
|
||||
|
||||
@@ -2,20 +2,23 @@ package com.baeldung.algorithms.linkedlist;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
@RunWith(value = Parameterized.class)
|
||||
public class CycleRemovalBruteForceTest extends CycleDetectionTestBase {
|
||||
boolean cycleExists;
|
||||
Node<Integer> head;
|
||||
|
||||
@Test
|
||||
public void givenNormalList_dontDetectLoop() {
|
||||
Node<Integer> root = createList();
|
||||
Assert.assertFalse(CycleRemovalBruteForce.detectAndRemoveCycle(root));
|
||||
public CycleRemovalBruteForceTest(Node<Integer> head, boolean cycleExists) {
|
||||
super();
|
||||
this.cycleExists = cycleExists;
|
||||
this.head = head;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCyclicList_detectAndRemoveLoop() {
|
||||
Node<Integer> root = createList();
|
||||
createLoop(root);
|
||||
Assert.assertTrue(CycleRemovalBruteForce.detectAndRemoveCycle(root));
|
||||
Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(root));
|
||||
public void givenList_ifLoopExists_thenDetectAndRemoveLoop() {
|
||||
Assert.assertEquals(cycleExists, CycleRemovalBruteForce.detectAndRemoveCycle(head));
|
||||
Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(head).cycleExists);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,20 +2,23 @@ package com.baeldung.algorithms.linkedlist;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
@RunWith(value = Parameterized.class)
|
||||
public class CycleRemovalByCountingLoopNodesTest extends CycleDetectionTestBase {
|
||||
boolean cycleExists;
|
||||
Node<Integer> head;
|
||||
|
||||
@Test
|
||||
public void givenNormalList_dontDetectLoop() {
|
||||
Node<Integer> root = createList();
|
||||
Assert.assertFalse(CycleRemovalByCountingLoopNodes.detectAndRemoveCycle(root));
|
||||
public CycleRemovalByCountingLoopNodesTest(Node<Integer> head, boolean cycleExists) {
|
||||
super();
|
||||
this.cycleExists = cycleExists;
|
||||
this.head = head;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCyclicList_detectAndRemoveLoop() {
|
||||
Node<Integer> root = createList();
|
||||
createLoop(root);
|
||||
Assert.assertTrue(CycleRemovalByCountingLoopNodes.detectAndRemoveCycle(root));
|
||||
Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(root));
|
||||
public void givenList_ifLoopExists_thenDetectAndRemoveLoop() {
|
||||
Assert.assertEquals(cycleExists, CycleRemovalByCountingLoopNodes.detectAndRemoveCycle(head));
|
||||
Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(head).cycleExists);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,20 +2,23 @@ package com.baeldung.algorithms.linkedlist;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
@RunWith(value = Parameterized.class)
|
||||
public class CycleRemovalWithoutCountingLoopNodesTest extends CycleDetectionTestBase {
|
||||
boolean cycleExists;
|
||||
Node<Integer> head;
|
||||
|
||||
@Test
|
||||
public void givenNormalList_dontDetectLoop() {
|
||||
Node<Integer> root = createList();
|
||||
Assert.assertFalse(CycleRemovalWithoutCountingLoopNodes.detectAndRemoveCycle(root));
|
||||
public CycleRemovalWithoutCountingLoopNodesTest(Node<Integer> head, boolean cycleExists) {
|
||||
super();
|
||||
this.cycleExists = cycleExists;
|
||||
this.head = head;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCyclicList_detectAndRemoveLoop() {
|
||||
Node<Integer> root = createList();
|
||||
createLoop(root);
|
||||
Assert.assertTrue(CycleRemovalWithoutCountingLoopNodes.detectAndRemoveCycle(root));
|
||||
Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(root));
|
||||
public void givenList_ifLoopExists_thenDetectAndRemoveLoop() {
|
||||
Assert.assertEquals(cycleExists, CycleRemovalWithoutCountingLoopNodes.detectAndRemoveCycle(head));
|
||||
Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(head).cycleExists);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user