算法排序篇-4【归并排序】js解法

69 阅读1分钟

归并排序

基本思想

归并排序是一种分而治之算法。它将原始数组切分成较小的数组,直到切分成只有一项的数组,最后将小数组归并为大数组。

基本思路

找到数组的中间位,以此为边界来划分左边的数组后右边的数组,并继续递归左边和右边的数组,继续拆分成若干个数组直至每个小数组中只包含一个元素,然后比较左数组的项是否比右数组的项小。如果是,则将该项从left数组添加到归并结果数组,并递增用于迭代数组的控制变量;否则,从right数组添加项并递增用于迭代数组的控制变量。最后将归并的左数组与右数组合并。

归并过程图示

归并过程图示.png

解法

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)),可以实际使用的算法,归并排序性能不错。