diff --git a/core-java/src/main/java/com/baeldung/linkedlist/LinkedList.java b/core-java/src/main/java/com/baeldung/linkedlist/LinkedList.java new file mode 100644 index 0000000000..12c73f2489 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/linkedlist/LinkedList.java @@ -0,0 +1,58 @@ +package com.baeldung.linkedlist; + +/** + * Implementation of a singly linked list. + */ +public class LinkedList { + private Node head; + private Node tail; + + public Node head() { + return head; + } + + public void add(String data) { + Node newNode = new Node(data); + + if (head == null) { + head = newNode; + tail = newNode; + } else { + tail.next = newNode; + tail = newNode; + } + } + + public static class Node { + private Node next; + private String data; + + public Node(String data) { + this.data = data; + } + + public String data() { + return data; + } + + public void setData(String data) { + this.data = data; + } + + public boolean hasNext() { + return next != null; + } + + public Node next() { + return next; + } + + public void setNext(Node next) { + this.next = next; + } + + public String toString() { + return this.data; + } + } +} diff --git a/core-java/src/main/java/com/baeldung/linkedlist/MiddleElementLookup.java b/core-java/src/main/java/com/baeldung/linkedlist/MiddleElementLookup.java new file mode 100644 index 0000000000..27684c93d2 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/linkedlist/MiddleElementLookup.java @@ -0,0 +1,79 @@ +package com.baeldung.linkedlist; + +import com.baeldung.linkedlist.LinkedList.Node; + +public class MiddleElementLookup { + + public static String findMiddleElement(Node head) { + if (head == null) { + return null; + } + + // calculate the size of the list + Node current = head; + int size = 1; + while (current.hasNext()) { + current = current.next(); + size++; + } + + // iterate till the middle element + current = head; + for (int i = 0; i < (size - 1) / 2; i++) { + current = current.next(); + } + + return current.data(); + } + + public static String findMiddleElement1PassRecursively(Node head) { + if (head == null) { + return null; + } + + MiddleAuxRecursion middleAux = new MiddleAuxRecursion(); + findMiddleRecursively(head, middleAux); + return middleAux.middle.data(); + } + + private static void findMiddleRecursively(Node node, MiddleAuxRecursion middleAux) { + if (node == null) { + // reached the end + middleAux.length = middleAux.length / 2; + return; + } + middleAux.length++; + findMiddleRecursively(node.next(), middleAux); + + if (middleAux.length == 0) { + // found the middle + middleAux.middle = node; + } + + middleAux.length--; + } + + public static String findMiddleElement1PassIteratively(Node head) { + if (head == null) { + return null; + } + + Node slowPointer = head; + Node fastPointer = head; + + while (fastPointer.hasNext() && fastPointer.next() + .hasNext()) { + fastPointer = fastPointer.next() + .next(); + slowPointer = slowPointer.next(); + } + + return slowPointer.data(); + } + + private static class MiddleAuxRecursion { + Node middle; + int length = 0; + } + +} diff --git a/core-java/src/test/java/com/baeldung/linkedlist/MiddleElementLookupUnitTest.java b/core-java/src/test/java/com/baeldung/linkedlist/MiddleElementLookupUnitTest.java new file mode 100644 index 0000000000..d456259612 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/linkedlist/MiddleElementLookupUnitTest.java @@ -0,0 +1,58 @@ +package com.baeldung.linkedlist; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class MiddleElementLookupUnitTest { + + @Test + public void whenFindingMiddle_thenMiddleFound() { + String middle = MiddleElementLookup.findMiddleElement(createList(5).head()); + assertEquals("3", middle); + + middle = MiddleElementLookup.findMiddleElement(createList(4).head()); + assertEquals("2", middle); + } + + @Test + public void whenFindingMiddle1PassRecursively_thenMiddleFound() { + String middle = MiddleElementLookup.findMiddleElement1PassRecursively(createList(5).head()); + assertEquals("3", middle); + + middle = MiddleElementLookup.findMiddleElement1PassRecursively(createList(4).head()); + assertEquals("2", middle); + } + + @Test + public void whenFindingMiddle1PassIteratively_thenMiddleFound() { + String middle = MiddleElementLookup.findMiddleElement1PassIteratively(createList(5).head()); + assertEquals("3", middle); + + middle = MiddleElementLookup.findMiddleElement1PassIteratively(createList(4).head()); + assertEquals("2", middle); + } + + @Test + public void whenListEmptyOrNull_thenMiddleNull() { + String middle = MiddleElementLookup.findMiddleElement(null); + assertEquals(null, middle); + + middle = MiddleElementLookup.findMiddleElement1PassIteratively(null); + assertEquals(null, middle); + + middle = MiddleElementLookup.findMiddleElement1PassRecursively(null); + assertEquals(null, middle); + } + + private static LinkedList createList(int n) { + LinkedList list = new LinkedList(); + + for (int i = 1; i <= n; i++) { + list.add(String.valueOf(i)); + } + + return list; + } + +}