diff --git a/src/main/java/com/thealgorithms/datastructures/lists/README.md b/src/main/java/com/thealgorithms/datastructures/lists/README.md index 6aefa4c98e6d..5a19c3bfa990 100644 --- a/src/main/java/com/thealgorithms/datastructures/lists/README.md +++ b/src/main/java/com/thealgorithms/datastructures/lists/README.md @@ -30,3 +30,4 @@ The `next` variable points to the next node in the data structure and value stor 6. `MergeKSortedLinkedlist.java` : Merges K sorted linked list with mergesort (mergesort is also the most efficient sorting algorithm for linked list). 7. `RandomNode.java` : Selects a random node from given linked list and diplays it. 8. `SkipList.java` : Data Structure used for storing a sorted list of elements with help of a Linked list hierarchy that connects to subsequences of elements. +9. `TortoiseHareAlgo.java` : Finds the middle element of a linked list using the fast and slow pointer (Tortoise-Hare) algorithm. diff --git a/src/main/java/com/thealgorithms/datastructures/lists/TortoiseHareAlgo.java b/src/main/java/com/thealgorithms/datastructures/lists/TortoiseHareAlgo.java new file mode 100644 index 000000000000..9d803003c658 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/lists/TortoiseHareAlgo.java @@ -0,0 +1,63 @@ +package com.thealgorithms.datastructures.lists; + +public class TortoiseHareAlgo { + static final class Node { + Node next; + E value; + + private Node(E value, Node next) { + this.value = value; + this.next = next; + } + } + + private Node head = null; + + public TortoiseHareAlgo() { + head = null; + } + + public void append(E value) { + Node newNode = new Node<>(value, null); + if (head == null) { + head = newNode; + return; + } + Node current = head; + while (current.next != null) { + current = current.next; + } + current.next = newNode; + } + + public E getMiddle() { + if (head == null) { + return null; + } + + Node slow = head; + Node fast = head; + + while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + } + + return slow.value; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("["); + Node current = head; + while (current != null) { + sb.append(current.value); + if (current.next != null) { + sb.append(", "); + } + current = current.next; + } + sb.append("]"); + return sb.toString(); + } +} diff --git a/src/test/java/com/thealgorithms/datastructures/lists/TortoiseHareAlgoTest.java b/src/test/java/com/thealgorithms/datastructures/lists/TortoiseHareAlgoTest.java new file mode 100644 index 000000000000..2804534c988c --- /dev/null +++ b/src/test/java/com/thealgorithms/datastructures/lists/TortoiseHareAlgoTest.java @@ -0,0 +1,46 @@ +package com.thealgorithms.datastructures.lists; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +import org.junit.jupiter.api.Test; + +class TortoiseHareAlgoTest { + + @Test + void testAppendAndToString() { + TortoiseHareAlgo list = new TortoiseHareAlgo<>(); + list.append(10); + list.append(20); + list.append(30); + assertEquals("[10, 20, 30]", list.toString()); + } + + @Test + void testGetMiddleOdd() { + TortoiseHareAlgo list = new TortoiseHareAlgo<>(); + list.append(1); + list.append(2); + list.append(3); + list.append(4); + list.append(5); + assertEquals(3, list.getMiddle()); + } + + @Test + void testGetMiddleEven() { + TortoiseHareAlgo list = new TortoiseHareAlgo<>(); + list.append(1); + list.append(2); + list.append(3); + list.append(4); + assertEquals(3, list.getMiddle()); // returns second middle + } + + @Test + void testEmptyList() { + TortoiseHareAlgo list = new TortoiseHareAlgo<>(); + assertNull(list.getMiddle()); + assertEquals("[]", list.toString()); + } +}