(双)选择排序
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('===================');
}
}