BAEL-1773 Find the middle element of a Linked List. (#4350)

* BAEL-1773 - find middle element of linked list

* changes from review

* changes from review
This commit is contained in:
Marcos Lopez Gonzalez 2018-05-28 21:20:37 +02:00 committed by Predrag Maric
parent 14a1b90ed9
commit 260e805b69
3 changed files with 195 additions and 0 deletions

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}