Search code examples
c++algorithmmergesort

How to find the low & high in Merge Sort


I have a basic understanding of the Merge Sort algorithm. But for some reason I can't wrap my head around where the values from low and high are coming from. This is the code I am working with for Merge.

void practiceMerge(int a[], int low, int mid, int high)
{
    int b[10000];
    int i = low, j = mid + 1, k = 0;

    while (i <= mid && j <= high) {
        if (a[i] <= a[j])
            b[k++] = a[i++];
        else
            b[k++] = a[j++];
    }
    while (i <= mid)
    b[k++] = a[i++];

    while (j <= high)
        b[k++] = a[j++];

    k--;
    while (k >= 0) {
        a[low + k] = b[k];
        k--;
    }
}

Solution

  • Let me explain by commenting your code:

    //Sort an array a from its index low to its index high by merging two
    //subarrays of a that go from low to mid and mid to high.
    void practiceMerge(int a[], int low, int mid, int high)
    {
        int b[10000]; //Buffer
        int i = low; //starting index in first sub array
        int j = mid + 1; //starting index in second sub array
        int k = 0; //starting index in buffer
    
        //While you DO NOT go beyond the limit of the first subarray
        //nor the second
        while (i <= mid && j <= high) {
            if (a[i] <= a[j])
                //Put the value of the first subarray, and move 
                b[k++] = a[i++];
            else
                //Put the value of the first subarray, and move
                b[k++] = a[j++];
        }
        //Finish copying first subarray if not done yet
        while (i <= mid)
        b[k++] = a[i++];
        //Finish copying second subarray if not done yet
        while (j <= high)
            b[k++] = a[j++];
    
        //Copy buffer to array a
        k--;
        while (k >= 0) {
            a[low + k] = b[k];
            k--;
        }
    }
    

    Basically, the low, mid and high, are the borders of the array "a" that you are looking at. "a" could be bigger. Ex:

    a =  3 2 1 5 6 7 0 1 
    low = 0
    mid = 2
    high = 4
    

    Here you are sorting the first half of a.

    EDIT: Your function merges the arrays. The main merge sort function, splits the array. It would be:

    void merge_sort(int a[], int lo, int hi) {
       if (low >= hi)
          return; //Nothing to sort
       int mid = (lo+hi)/2; //The guy between lo and hi.
       merge_sort(a,lo, mid); //sort the left
       merge_sort(a, mid, hi); //sort the right
       practiceMerge(a, lo, mid, hi); //This merges the array
    }
    

    To understand (don't just copy paste!) think of it this way: merge_sort sorts a chunk of array, not the entire array, just the bit between lo and hi. In order to do so, it sorts one half, then the other. Then it merges that result into the array. Therefore, Inside merge_sort, the "hi" and "lo" are computed from the parameter. Now, YOU, THE USER, might want to sort the array from 0 to the end, or from 10th to 99th index. That is your choice. And that is the parameters you pass to your call.

    void main() {
       //Bla bla bla
       merge_sort(songs, 89, 250); //Only sort some songs
    }
    

    Think of this, as a black box. You call it with some parameters, the box does its thing. Because the box uses itself, it knows how to call itself (i.e. it know how to compute low, high and mid) but the initial call in the recursion is your responsability as the user.

    P.S.: I feel like Im not being very clear...