All files / datamodel/src/operator merge-sort.js

100% Statements 35/35
100% Branches 15/15
100% Functions 4/4
100% Lines 34/34

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92                218x 218x 218x 109x   109x 107x   2x                           189x 189x 189x 848x   189x 189x   189x 848x 97x 97x 751x 140x 140x 611x 317x 317x   294x 294x                               402x   189x 189x 189x 189x   189x                         25x 24x   25x    
/**
 * The default sort function.
 *
 * @param {*} a - The first value.
 * @param {*} b - The second value.
 * @return {number} Returns the comparison result e.g. 1 or 0 or -1.
 */
function defSortFn (a, b) {
    const a1 = `${a}`;
    const b1 = `${b}`;
    if (a1 < b1) {
        return -1;
    }
    if (a1 > b1) {
        return 1;
    }
    return 0;
}
 
/**
 * The helper function for merge sort which creates the sorted array
 * from the two halves of the input array.
 *
 * @param {Array} arr - The target array which needs to be merged.
 * @param {number} lo - The starting index of the first array half.
 * @param {number} mid - The ending index of the first array half.
 * @param {number} hi - The ending index of the second array half.
 * @param {Function} sortFn - The sort function.
 */
function merge (arr, lo, mid, hi, sortFn) {
    const mainArr = arr;
    const auxArr = [];
    for (let i = lo; i <= hi; i += 1) {
        auxArr[i] = mainArr[i];
    }
    let a = lo;
    let b = mid + 1;
 
    for (let i = lo; i <= hi; i += 1) {
        if (a > mid) {
            mainArr[i] = auxArr[b];
            b += 1;
        } else if (b > hi) {
            mainArr[i] = auxArr[a];
            a += 1;
        } else if (sortFn(auxArr[a], auxArr[b]) <= 0) {
            mainArr[i] = auxArr[a];
            a += 1;
        } else {
            mainArr[i] = auxArr[b];
            b += 1;
        }
    }
}
 
/**
 * The helper function for merge sort which would be called
 * recursively for sorting the array halves.
 *
 * @param {Array} arr - The target array which needs to be sorted.
 * @param {number} lo - The starting index of the array half.
 * @param {number} hi - The ending index of the array half.
 * @param {Function} sortFn - The sort function.
 * @return {Array} Returns the target array itself.
 */
function sort (arr, lo, hi, sortFn) {
    if (hi === lo) { return arr; }
 
    const mid = lo + Math.floor((hi - lo) / 2);
    sort(arr, lo, mid, sortFn);
    sort(arr, mid + 1, hi, sortFn);
    merge(arr, lo, mid, hi, sortFn);
 
    return arr;
}
 
/**
 * The implementation of merge sort.
 * It is used in DataModel for stable sorting as it is not sure
 * what the sorting algorithm used by browsers is stable or not.
 *
 * @param {Array} arr - The target array which needs to be sorted.
 * @param {Function} [sortFn=defSortFn] - The sort function.
 * @return {Array} Returns the input array itself in sorted order.
 */
export function mergeSort (arr, sortFn = defSortFn) {
    if (arr.length > 1) {
        sort(arr, 0, arr.length - 1, sortFn);
    }
    return arr;
}