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:
parent
14a1b90ed9
commit
260e805b69
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue