javaalgorithmlinked-listmergesort

Sorting A LL using Merge Sort in Java


I am trying to sort a Linked List using mergesort in Java. However, I am not getting the sorted Linked List as output. This is the code:-

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode sortList(ListNode head) {
        if(head==null||head.next==null){
            return head;
        }
        ListNode middle = findMiddle(head);
        ListNode rightHead = middle.next;
        middle.next = null;
        ListNode leftHead = head;
        leftHead = sortList(leftHead);
        rightHead = sortList(rightHead);

        return merge(leftHead,rightHead);
    }
    public ListNode merge(ListNode leftHead, ListNode rightHead){
        ListNode dummyHead = new ListNode(-1);
        ListNode temp = dummyHead;
        while(leftHead!=null && rightHead!=null){
            if(leftHead.val<rightHead.val){
                temp.next = leftHead;
                temp = leftHead;
                leftHead = leftHead.next;
            }else{
                temp.next = rightHead;
                temp = rightHead;
                rightHead = rightHead.next;
            }
            // temp = temp.next;
        }
        if(leftHead!=null){
            temp.next = new ListNode(leftHead.val);
            leftHead = leftHead.next;
            temp = temp.next;
            }
        else if(rightHead!=null){
            temp.next = new ListNode(rightHead.val);
            rightHead = rightHead.next;
            temp = temp.next;      
        }
        return dummyHead.next;
    }
    public ListNode findMiddle(ListNode head){
        ListNode slow = head;
        ListNode fast = head.next;
        while(fast!=null && fast.next!=null){
            slow = slow.next;
            fast = fast.next.next;
        }
        return slow;
    }
}

I have used the standard mergeSort algorithm which is used to sort Arrays just the data type is changed to Linked List. There are no compiler errors so I guess something has to be wrong with my logic.


Solution

  • Your issue is in the merge function. After the first while loop, you are using a if-else case which just merging only 1 node, but it should be merged through while loop to merge the whole remaining part.

    For example :
    left = [2, 3]
    right = [1]
    according to your code : after end of while loop : mergedList = [1] then if(leftHead!=null) satisfy. After that if condition : mergedList = [1, 3] but there is still a node remaining in left part.

    while(leftHead!=null){
        temp.next = new ListNode(leftHead.val);
        leftHead = leftHead.next;
        temp = temp.next;
    }
    while(rightHead!=null){
        temp.next = new ListNode(rightHead.val);
        rightHead = rightHead.next;
        temp = temp.next;      
    }
    

    But, you can use if-else too as it's a LinkedList. You can do as following, when you are just adding the remaining part in the end, that might save your code a little running time too.

    if(leftHead!=null){
        temp.next = leftHead;
    }
    else if(rightHead!=null){
        temp.next = rightHead;     
    }