Last time I started with the simplest question of reversing a linked list this time let me go a bit further – sorting a linked list.

Just for a minute consider sorting a linked list , some of the standard sorting mechanism assumes random access of data (like quick sort, heapsort ) so linked list becomes a special case. But then we have one more wonderful sort left to consider , which is merge sort. Merge sort is very special (in fact many standard sort libraries like in java internally uses a combination of merge sort and insertion sort) because it has the wonderful property of being a stable sort. In fact it is the only stable sort with asymptotic complexity of O(nlogn) but its draw back typically is the use of O(n) extra space. There are wonderful inline merge sort algorithms which I would cover in a different post altogether. Now what is more wonderful is that for sorting linked list, we can use merge sort’s O(nlogn) without the drawback of O(n) space. Again a quick search in net seem to suggest it is a very complicated algorithm to implement , again I am not sure why , this is my version of it (in Java).

The basic idea of merge sort is this basic recursive idea , how most of us learned recursion to start with -

merge_sort(list) {
  split list into two halfs, say first and second ;
  merge_sort(firstHalf);
  merge_sort(secondHalf);
  merge(firstHalf,secondHalf);
}

A working implementation in Java :


    public Node merge_sort(Node head) {
        if(head == null || head.next == null) { return head; }
        Node middle = getMiddle(head);      //get the middle of the list
        Node sHalf = middle.next; middle.next = null;   //split the list into two halfs

        return merge(merge_sort(head),merge_sort(sHalf));  /recurse on that
    }

    public Node merge(Node a, Node b) {
        Node dummyHead, curr; dummyHead = new Node(); curr = dummyHead;
        while(a !=null && b!= null) {
            if(a.info <= b.info) { curr.next = a; a = a.next; }
            else { curr.next = b; b = b.next; }
            curr = curr.next;
        }
        curr.next = (a == null) ? b : a;
        return dummyHead.next;
    }

    public Node getMiddle(Node head) {
        if(head == null) { return head; }
        Node slow, fast; slow = fast = head;
        while(fast.next != null && fast.next.next != null) {
            slow = slow.next; fast = fast.next.next;
        }
        return slow;
    }

View Comments to “Merge sort of linked list”

Post comment

You must be logged in to post a comment.

blog comments powered by Disqus