归并排序
基本思想
归并排序是一种分而治之算法。它将原始数组切分成较小的数组,直到切分成只有一项的数组,最后将小数组归并为大数组。
基本思路
找到数组的中间位,以此为边界来划分左边的数组后右边的数组,并继续递归左边和右边的数组,继续拆分成若干个数组直至每个小数组中只包含一个元素,然后比较左数组的项是否比右数组的项小。如果是,则将该项从left数组添加到归并结果数组,并递增用于迭代数组的控制变量;否则,从right数组添加项并递增用于迭代数组的控制变量。最后将归并的左数组与右数组合并。
归并过程图示
解法
let array = [3, 2, 15, 4, 1, 8]
function mergeSort(array) {
if (array.length > 1) { // 如果数组长度大于1才进行拆分数组
const { length } = array
const middle = Math.floor(length / 2) // 取数组的中间索引
const left = mergeSort(array.slice(0, middle)) // 递归拆分左数组
const right = mergeSort(array.slice(middle, length)) // 递归拆分右数组
array = merge(left, right) // 归并并排序
}
return array
}
function merge(left, right) {
let i = 0 // 左数组索引
let j = 0 // 右数组索引
const result = [] // 结果数组
while (i < left.length && j < right.length) {
result.push(compare(left[i], right[j]) ? left[i++] : right[j++]) // 比较左右数组项,如果左边小,递增左边,否则递增右数组
}
return result.concat(i < left.length ? left.slice(i) : right.slice(j)) // 合并左数组和右数组
}
function compare(a, b) {
return a < b
}
console.log(mergeSort(array));
性能
复杂度为O(nlog(n)),可以实际使用的算法,归并排序性能不错。