function mergeSort(arr, left, right) {
// base case
if (left >= right) return 0;
const mid = Math.floor(left + (right - left) / 2);
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
merge(arr, left, mid, right);
}
function merge(arr, left, mid, right) {
// 1. 使用一个临时数组,
// 将有序的左右两部分 [left, mid] 和 [mid + 1, right] 先合并到临时数组 sortedPart 中
const sortedPart = [];
let p = left,
q = mid + 1,
s = 0;
while (p <= mid && q <= right) {
if (arr[p] <= arr[q]) {
sortedPart[s++] = arr[p++];
} else {
sortedPart[s++] = arr[q++];
}
}
while (p <= mid) {
sortedPart[s++] = arr[p++];
}
while (q <= right) {
sortedPart[s++] = arr[q++];
}
// 2. 将 sortedPart 里面的元素一一更新到原数组中的对应位置
p = 0;
q = left;
while (p < sortedPart.length) {
arr[q++] = sortedPart[p++];
}
}
function mergeSort(arr) {
// base case
if (arr.length <= 1) return arr;
// 将数组一分为二,分别排序(两个子数组是拷贝)
const m = Math.floor(arr.length / 2);
const sortedLeft = mergeSort(arr.slice(0, m));
const sortedRight = mergeSort(arr.slice(m));
// 拿到排好序的 sortedLeft 和 sortedRight后,直接在原数组 arr 上合并成一个有序数组
let s = 0,
p = 0,
q = 0;
while (p < sortedLeft.length && q < sortedRight.length) {
if (sortedLeft[p] <= sortedRight[q]) {
arr[s++] = sortedLeft[p++];
} else {
arr[s++] = sortedRight[q++];
}
}
while (p < sortedLeft.length) {
arr[s++] = sortedLeft[p++];
}
while (q < sortedRight.length) {
arr[s++] = sortedRight[q++];
}
// 排好序后这个部分也需要返回
// arr 本身也是一个更大的数组的一部分
return arr;
}