简体   繁体   中英

Top down mergesort. Merge operation not clear

I'm learning about top down mergesort, and I am starting to understand the recursive part. I've seen a couple of implementations where the merge was done with a series of while loops.

However, in the below implementation the merge operation is different and it's not as clear how it works. It seems to just be comparing indexes and not actual elements (unlike other implementations I've seen)

     private void merge(int[] aux, int lo, int mid, int hi) {

        for (int k = lo; k <= hi; k++) {
            aux[k] = theArray[k]; 
        }

        int i = lo, j = mid+1;
        for (int k = lo; k <= hi; k++) {
            if (i > mid) {
                theArray[k] = aux[j++];
            }
            else if (j > hi) {
                theArray[k] = aux[i++];
            }
            else if (aux[j] < aux[i]) {
                theArray[k] = aux[j++];
            }
            else {
                theArray[k] = aux[i++];
            }
        }
    }

    private void sort(int[] aux, int lo, int hi) {
        if (hi <= lo) 
            return;
        int mid = lo + (hi - lo) / 2;
        sort(aux, lo, mid);
        sort(aux, mid + 1, hi);
        merge(aux, lo, mid, hi);
    }

    public  void sort() {
        int[] aux = new int[theArray.length];
        sort(aux, 0, aux.length - 1);
    }

The above code assumes the global variable theArray exists.

This merge method simply uses a single loop instead of the 3 loops used in most implementations (at least most implementations I've seen).

The first two conditions handle the cases where all the elements from one of the two source arrays being merged has already been added to the merged array. These conditions are usually handled by separate loops that follow the first loop, and don't require comparison of elements from the two source arrays.

        if (i > mid) { // all the elements between lo and mid were already merged
                       // so all that is left to do is add the remaining elements 
                       // from aux[j] to aux[hi]
            theArray[k] = aux[j++];
        }
        else if (j > hi) { // all the elements between mid+1 and hi were already merged
                           // so all that is left to do is add the remaining elements 
                           // from aux[i] to aux[mid]
            theArray[k] = aux[i++];
        }
        else if (aux[j] < aux[i]) { // both source arrays are not done, so you have to
                                    // compare the current elements of both to determine
                                    // which one should come first
            theArray[k] = aux[j++];
        }
        else {
            theArray[k] = aux[i++];
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM