本质上是“分治”,分而治之。其思想就是将一个大问题分解为若干个子问题,针对子问题分别求解后,再将子问题的解整合为大问题的解。

思路

  • 将需要被排序的数组从中间分割为两半,然后再将分割出来的每个子数组各分割为两半,重复以上操作,直到单个子数组只有一个元素为止。
  • 从粒度最小的子数组开始,两两合并、确保每次合并出来的数组都是有序的。当数组被合并至原有的规模时,就得到了一个完全排序的数组(时间复杂度为O(nlog(n))) ```javascript function mergeSort(arr) {
    1. // 先进行类型判断
    if(!Array.isArray(arr)){
    1. throw new TypeError('类型应为');
    } const len = arr.length // 处理边界情况 if(len <= 1) {
    1. return arr
    }
    // 计算分割点 const mid = Math.floor(len / 2)
    // 递归分割左子数组,然后合并为有序数组 const leftArr = mergeSort(arr.slice(0, mid)) // 递归分割右子数组,然后合并为有序数组 const rightArr = mergeSort(arr.slice(mid,len))
    // 合并左右两个有序数组 arr = mergeArr(leftArr, rightArr)
    // 返回合并后的结果 return arr }

function mergeArr(arr1, arr2) {
// 初始化两个指针,分别指向 arr1 和 arr2 let i = 0, j = 0
// 初始化结果数组 const res = []
// 缓存arr1的长度 const len1 = arr1.length
// 缓存arr2的长度 const len2 = arr2.length
// 合并两个子数组 while(i < len1 && j < len2) { if(arr1[i] < arr2[j]) { res.push(arr1[i]) i++ } else { res.push(arr2[j]) j++ } } // 若其中一个子数组首先被合并完全,则直接拼接另一个子数组的剩余部分 if(i<len1) { return res.concat(arr1.slice(i)) } else { return res.concat(arr2.slice(j)) } } ```