1
function mergesort(arr, left, right) {
    if (left < right) {
        let mid = parseInt((right - left) / 2) + left;
        mergesort(arr, left, mid);
        mergesort(arr, mid + 1, right);
        merge(arr, left, mid, right);
    }
}

function merge(arr, left, mid, right) {
    let i = left, j = mid + 1, k = 0, temp = [];
    while (i <= mid && j <= right) {
        if (arr[i] <= arr[j]) {
            temp[k] = arr[i];
            i++;
            k++;
        } else {
            temp[k] = arr[j];
            j++;
            k++;
        }
    }
    for (; i <= mid; i++) {
        temp[k] = arr[i];
        k++;
    }
    for (; j <= right; j++) {
        temp[k] = arr[j];
        k++;
    }
    for (let i = left; i <= right; i++) {
        arr[i] = temp[i];
    }
}

let arr = [ 5, 3, 7, 2, 9, 12, 4 ];
n = arr.length;
mergesort(arr, 0, n);

Please help me to find the bugs in the mergesort code. It prints this output: [undefined, undefined, undefined, undefined, undefined, undefined, 3, 5]. Why it is not working properly.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • 3
    https://ericlippert.com/2014/03/05/how-to-debug-small-programs/ – Barmar Jun 13 '23 at 16:33
  • Welcome to Stack Overflow! This is a good opportunity for you to start familiarizing yourself with [using a debugger](https://stackoverflow.com/q/25385173/328193). When you step through the code in a debugger, which operation first produces an unexpected result? What were the values used in that operation? What was the result? What result was expected? Why? To learn more about this community and how we can help you, please start with the [tour] and read [ask] and its linked resources. – David Jun 13 '23 at 16:37
  • off by 1 error... – epascarello Jun 13 '23 at 16:44

1 Answers1

0

The mistake is in the last for loop, copying the temp array back to the arr slice: you use the same index i in both arrays whereas you should use two different index variables to index into temp from 0 to k excluded and into arr from left to right inclusive.

Here is a modified loop:

    for (i = 0; i < k; i++) {
        arr[left + i] = temp[i];
    }

Note also these remarks:

  • to perform integer division by 2, you should use (right - left) >> 2 instead of converting to a string and parsing back as an integer, a much more costly operation.
  • copying the remaining elements from arr to temp in the penultimate for loop is useless since these elements are already in the proper place.
  • you pass n to the initial call as the right index: this is inconsistent with your mergesort function semantics that expects right to be the index to the last element, not one past it.

It is actually more idiomatic in javascript and similar languages with 0 based arrays to consider right to be the latter (index past the last element). Here is a modified version with this semantic change:

function mergesort(arr, left, right) {
    if (right - left > 1) {
        let mid = left + ((right - left) >> 1);
        mergesort(arr, left, mid);
        mergesort(arr, mid, right);
        merge(arr, left, mid, right);
    }
}

function merge(arr, left, mid, right) {
    let i = left, j = mid, k = 0, temp = [];
    while (i < mid && j < right) {
        if (arr[i] <= arr[j]) {
            temp[k++] = arr[i++];
        } else {
            temp[k++] = arr[j++];
        }
    }
    while (i < mid) {
        temp[k++] = arr[i++];
    }
    for (i = 0; i < k; i++) {
        arr[left + i] = temp[i];
    }
}

let arr = [ 5, 3, 7, 2, 9, 12, 4 ];
mergesort(arr, 0, arr.length);
chqrlie
  • 131,814
  • 10
  • 121
  • 189