diff --git a/src/main/java/com/thealgorithms/datastructures/lists/FindMiddleOfSinglyLinkedList.java b/src/main/java/com/thealgorithms/datastructures/lists/FindMiddleOfSinglyLinkedList.java new file mode 100644 index 000000000000..79c71d0f2dcf --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/lists/FindMiddleOfSinglyLinkedList.java @@ -0,0 +1,39 @@ +package com.thealgorithms.datastructures.lists; + +public final class FindMiddleOfSinglyLinkedList { + + static final class Node { + public Node next; + public E value; + + Node(E value, Node next) { + this.value = value; + this.next = next; + } + } + + /** + * Finds the middle node of a singly linked list. + * + * @param head the head node of the singly linked list + * @param the type of elements in the linked list + * @return the middle node of the linked list; if the list is empty, returns null + */ + public static Node findMiddle(Node head) { + if (head == null) { + return null; // Empty list + } + + Node slowPointer = head; + Node fastPointer = head; + + // Move fastPointer two steps and slowPointer one step at a time + while (fastPointer != null && fastPointer.next != null) { + slowPointer = slowPointer.next; + fastPointer = fastPointer.next.next; + } + + // When fastPointer reaches the end, slowPointer will be at the middle + return slowPointer; + } +} diff --git a/src/test/java/com/thealgorithms/datastructures/lists/FindMiddleOfSinglyLinkedListTest.java b/src/test/java/com/thealgorithms/datastructures/lists/FindMiddleOfSinglyLinkedListTest.java new file mode 100644 index 000000000000..ecedae8ca3d3 --- /dev/null +++ b/src/test/java/com/thealgorithms/datastructures/lists/FindMiddleOfSinglyLinkedListTest.java @@ -0,0 +1,49 @@ +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; + +final class FindMiddleOfSinglyLinkedListTest { + + @Test + void testFindMiddleEmptyList() { + FindMiddleOfSinglyLinkedList.Node head = null; + var middle = FindMiddleOfSinglyLinkedList.findMiddle(head); + assertNull(middle, "Middle of an empty list should be null."); + } + + @Test + void testFindMiddleSingleElement() { + var head = new FindMiddleOfSinglyLinkedList.Node<>(1, null); + var middle = FindMiddleOfSinglyLinkedList.findMiddle(head); + assertEquals(1, middle.value, + "Middle of a single-element list should be the only element."); + } + + @Test + void testFindMiddleOddElements() { + var head = new FindMiddleOfSinglyLinkedList.Node<>(1, + new FindMiddleOfSinglyLinkedList.Node<>(2, + new FindMiddleOfSinglyLinkedList.Node<>(3, + new FindMiddleOfSinglyLinkedList.Node<>(4, + new FindMiddleOfSinglyLinkedList.Node<>(5, null))))); + + var middle = FindMiddleOfSinglyLinkedList.findMiddle(head); + assertEquals(3, middle.value, + "Middle of a 5-element list should be the 3rd element."); + } + + @Test + void testFindMiddleEvenElements() { + var head = new FindMiddleOfSinglyLinkedList.Node<>(1, + new FindMiddleOfSinglyLinkedList.Node<>(2, + new FindMiddleOfSinglyLinkedList.Node<>(3, + new FindMiddleOfSinglyLinkedList.Node<>(4, null)))); + + var middle = FindMiddleOfSinglyLinkedList.findMiddle(head); + assertEquals(3, middle.value, + "Middle of a 4-element list should be the 3rd element."); + } +}