Merge Sort for Singly Linked List seems to remove any numbers larger than the final number I input into the list

fourteen14 :

I am currently trying to formulate a mergeSort mechanism for a singly linked list. Through research and finding consistent ideas about A) a merge sort being the best way to sort a singly linked list, and B) that these are the key components for performing such an operation, I have arrived at this following code. It almost works exactly as intended, but will only return all of the integers larger than the last inputted number. For example, inputting 7, 6, 5, 4, 3, 2, 1 will return 1, 2, 3, 4, 5, 6, 7, but inputting 1, 2, 3, 4, 5 will only return 5. I've used random input orders so it's not a problem localised to just inputting the numbers in reverse order, but literally any order. If a number is smaller than the final number, it gets removed from the list in the sort process. I cannot locate the cause for this at all. My original problem was caused by an errant while loop that was stopping the iterations after one go, so once I removed that the merge sort was working, but for this problem I have just described.

Any and all advice or suggestions are more than welcome, and thanks for any input you have. My knowledge of linked lists and recursion isn't the greatest, so I really welcome all input/constructive criticism here.

    public Node mergeSort(Node head) {
    if (head == null || head.getNext() == null) return head;
    Node midpoint = findMidpoint(head);
    Node rightliststart = midpoint.getNext();                       
    midpoint.setNext(null);                                                         
    Node rightlist = mergeSort(rightliststart);
    Node sorted = sort(leftlist, rightlist);
    return sorted;
}

  public Node findMidpoint(Node head) {                             
        if (head == null) return head;
        Node slowpointer = head;
        Node fastpointer = slowpointer.getNext();
        while (fastpointer != null) {
            fastpointer = fastpointer.getNext();
            if (fastpointer != null) {
                slowpointer = slowpointer.getNext();
                fastpointer = fastpointer.getNext();
            }
        }
        return slowpointer;
    }

    public Node sort(Node one, Node two) {
        Node temp = null;
        if (one == null) return two;
        if (two == null) return one;
        if (one.getData() <= two.getData()) {
            temp = one;
            temp.setNext(sort(one.getNext(), two));
        }
        else {
            temp = two;
            temp.setNext(sort(one, two.getNext()));
        }
        return temp;
    }
rcgldr :

Example merge code. This shows how the dummy node is used to simplify the code (avoids special case to update head on first node merged).

    // merge two already sorted lists
    static Node merge(Node list0, Node list1) {
        if(list0 == null)
            return list1;
        if(list1 == null)
            return list0;
        Node temp = new Node();         // dummy node
        Node dest = temp;
        while(true){
            if(list0.data <= list1.data){
                dest.next = list0;
                dest = list0;
                list0 = list0.next;
                if(list0 == null){
                    dest.next = list1;
                    break;
                }
            } else {
                dest.next = list1;
                dest = list1;
                list1 = list1.next;
                if(list1 == null){
                    dest.next = list0;
                    break;
                }
            }
        }
        return temp.next;
    }

Example top down merge sort code. It scans the list one time to get the size of the list to avoid double scanning (fast, slow), only scanning n/2 nodes for each recursive split.

    // return size of list
    static int size(Node head) {
    int i = 0;
        while(head != null){
            head = head.next;
            i++;
        }
        return i;
    }

    // advance to node n
    static Node advance(Node head, int n) {
        while(0 < n--)
            head = head.next;
        return head;
    }

    // top down merge sort for single link list entry function
    static Node sorttd(Node head) {
        int n = size(head);
        if(n < 2)
            return head;
        head = sorttdr(head, n);
        return head;
    }

    // top down merge sort for single link list recursive function
    static Node sorttdr(Node head, int n) {
        if(n < 2)
            return head;
        int n2 = (n/2);
        Node node = advance(head, n2-1);
        Node next = node.next;
        node.next = null;
        head = sorttdr(head, n2);
        next = sorttdr(next, n-n2);
        head = merge(head, next);
        return head;
    }

Example bottom up merge sort code. It uses a small (32) array of lists, where array[i] is a list with 2^i nodes. Nodes are merged into the array, then the array is merged into a single sorted list. On a large list that doesn't fit in cache, and with randomly scattered nodes, there will be a lot of cache misses for each node accessed, in which case bottom up merge sort is about 30% faster than top down.

    // bottom up merge sort for single link list
    static Node sortbu(Node head) {
        final int NUMLIST = 32;
        Node[] alist = new Node[NUMLIST];
        Node node;
        Node next;
        int i;
        // if < 2 nodes, return
        if(head == null || head.next == null)
            return null;
        node = head;
        // merge node into array
        while(node != null){
            next = node.next;
            node.next = null;
            for(i = 0; (i < NUMLIST) && (alist[i] != null); i++){
                node = merge(alist[i], node);
                alist[i] = null;
            }
            if(i == NUMLIST)   // don't go past end of array
                i--;
            alist[i] = node;
            node = next;
        }
        // node == null
        // merge array into single list
        for(i = 0; i < NUMLIST; i++)
            node = merge(alist[i], node);
        return node;
    }

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=34692&siteId=1