排序算法

(双)选择排序

export var selectionSort: ArraySortAlgo = (array, start = 0, end = array.length) => {
    for (var i = start; i < end; i++) {
        var max = i;
        for (var j = i + 1; j < end; j++) {
            if (array[j] > array[max]) {
                max = j;
            }
        }
        [array[max], array[i]] = [array[i], array[max]];
    }
}

export var doubleSelectionSort: ArraySortAlgo = (array, start = 0, end = array.length) => {
    var d = start + (end - start - 1) / 2;
    for (var i = start; i < d; i++) {
        var max = i;
        var min = end - i - 1 + start;
        for (var j = i; j < end - i + start; j++) {
            if (array[j] > array[max]) {
                max = j;
            } else if (array[j] < array[min]) {
                min = j;
            }
        }
        [array[max], array[i]] = [array[i], array[max]];
        // 如果min是max和i其中之一,则需要跟踪最新轨迹
        if (min === max) min = i;
        if (min === i) min = max;
        [array[min], array[end - i - 1 + start]] = [array[end - i - 1 + start], array[min]];
    }
}

归并排序

const DEBUG = false;

/**
 * merge s1 + s2:
 * ```
 * arr: [x, x, x, 9, 8, 7, 6, 5, 4, 3, 0, 3, 2, 1]
 *               |      -s1:8-        | |-s2:3-|
 *            start
 * ```
 * result:
 * ```
 * arr: [x, x, x, 9, 8, 7, 6, 5, 4, 3, 3, 2, 1, 0]
 * ```
 * @param arr 
 * @param start 
 * @param s1 
 * @param s2 
 */
function mergeArray(arr, start, s1, s2) { // s1大于s2
    var na = [];
    na.length = s1 + s2;

    var [p1, p2] = [0, s1];
    for (var i = 0; i < na.length; i++) {
        var max;
        // P(A)和P(B)可进一步优化
        if (p1 === s1) { // P(A)
            max = arr[start + p2++];
        } else if (p2 === na.length) { // P(B)
            max = arr[start + p1++];
        } else if (arr[start + p1] < arr[start + p2]) {
            // console.log(`比较${arr[start + p1]}和${arr[start + p2]}`);
            max = arr[start + p2++];
        } else {
            max = arr[start + p1++];
        }
        na[i] = max;
    }

    for (var j = 0; j < na.length; j++) { // write back
        arr[start + j] = na[j];
    }
    DEBUG && console.log('合并得', '========');
    DEBUG && console.log(na.join(' '));
}

export var mergeSort: ArraySortAlgo = (array, start = 0, end = array.length) => {
    // if (end - start < 2) return;

    var d = end - start;
    for (var setup = 1; setup < d; setup *= 2) { // setup 表示目前每setup个数组有序,1个数字当然是有序的,所以从1开始。之后该值必然是偶数
        for (var i = start; i < end; i += setup * 2) { // i 表示从该索引开始合并两个有序的子数组
            var n = end - i; // 末尾还有n个数需要合并
            var p1 = (n < setup) ? n : setup;
            var p2 = (n - p1 < setup) ? n - p1 : setup;
            DEBUG && console.log(`merge[${i}] (${array[i]})`, setup, `${p1}+${p2}`);
            mergeArray(array, i, p1, p2);
        }
        DEBUG && console.log(`${setup}排序后:`);
        DEBUG && console.log(array.join(' '));
        DEBUG && console.log('===================');
    }
}
原文地址:https://www.cnblogs.com/develon/p/14237876.html