package me.ramswaroop.linkedlists; import me.ramswaroop.common.SingleLinkedList; import me.ramswaroop.common.SingleLinkedNode; /** * Created by IntelliJ IDEA. * * @author: ramswaroop * @date: 7/7/15 * @time: 4:34 PM */ public class MergeSort { /** * Merge sort for linked list starting at {@param node}. * * Time complexity: O(n log n) * Space complexity: O(log n) stack space as it is recursive * * @param node * @param <E> * @return */ public static <E extends Comparable<E>> SingleLinkedNode<E> mergeSort(SingleLinkedNode<E> node) { if (node == null || node.next == null) return node; SingleLinkedNode<E> middleNode, head1, head2; middleNode = divideInTwoHalves(node); head1 = mergeSort(node); head2 = mergeSort(middleNode); return mergeTwoSortedLists(head1, head2); } /** * Divides a linked list starting from {@param node} into 2 halves * and returns the starting {@code node} of the second half. * * @param node * @param <E> * @return */ public static <E extends Comparable<E>> SingleLinkedNode<E> divideInTwoHalves(SingleLinkedNode<E> node) { SingleLinkedNode<E> slow = node, fast = node, prev = slow; if (node == null || node.next == null) { return null; } while (fast != null && fast.next != null) { prev = slow; slow = slow.next; fast = fast.next.next; } prev.next = null; return slow; } /** * Merges two sorted lists starting at {@param node1} and {@param node2} * into one and returns its starting node. * <p/> * This method is similar to {@link me.ramswaroop.linkedlists.MergeTwoSortedLists#mergeTwoSortedLists} * * @param node1 * @param node2 * @param <E> * @return */ public static <E extends Comparable<E>> SingleLinkedNode<E> mergeTwoSortedLists(SingleLinkedNode<E> node1, SingleLinkedNode<E> node2) { SingleLinkedNode<E> curr1 = node1, curr2 = node2, head, curr; if (node1 == null && node2 == null) return null; head = curr = new SingleLinkedNode<>(null); // dummy node while (curr1 != null || curr2 != null) { // handle cases where either of the list run out first if (curr1 == null) { curr.next = curr2; curr2 = curr2.next; } else if (curr2 == null) { curr.next = curr1; curr1 = curr1.next; } else if (curr1.item.compareTo(curr2.item) < 0) { // advance the current pointer of the // list having smaller {@code item} curr.next = curr1; curr1 = curr1.next; } else if (curr1.item.compareTo(curr2.item) > 0) { curr.next = curr2; curr2 = curr2.next; } else { // both nodes are equal so add both to the result curr.next = curr1; curr = curr.next; curr1 = curr1.next; curr.next = curr2; curr2 = curr2.next; } curr = curr.next; } // return the node next to the dummy node return head.next; } public static void main(String a[]) { SingleLinkedList<Integer> linkedList = new SingleLinkedList<>(); linkedList.add(21); linkedList.add(33); linkedList.add(89); linkedList.add(21); linkedList.add(44); linkedList.add(67); linkedList.printList(); linkedList.printList(mergeSort(linkedList.head)); } }