• 【拿下JS算法】:归并排序


    一、概念

    • “归并”:将两个已经排序的序列合并成一个序列的操作。
    • “归并排序”:创建在归并操作上的一种有效的排序算法,1945年由约翰·冯·诺伊曼首次提出。该算法是采用“分治法”的一个非常典型的应用,且各层分治递归可以同时进行。
    • “分治法”:“分而治之”,把一个复杂的问题分成两个或更多的相同或相似的子问题,直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。
      • 分割:递归地把当前序列平均分割成两半
      • 集成:在保持元素顺序的同时将上一步得到的子序列集成到一起(归并)

    二、特点

    稳定、高效(速度仅次于快速排序)、消耗空间。

    三、思想梳理

    现在有数组[12, 2 , 13, 23, 4, 45], 分步骤执行

    • 第一步:
      将原序列分割成长度为n的子序列
      [12] [2] [13] [23] [4] [45]
    • 第二步:
      每两个子序列进行对比,将结果放入一个新序列
      [12] [2] [13] [23] [4] [45]
      [2 , 12] [13, 23] [4, 45]
    • 第三步
      将第二步中新的序列再进行两两对比,重复此环节,得到最终结果
      [2 , 12] [13, 23] [4, 45]
      [2, 12, 13 23] [4, 45]
      [2, 4, 12, 13, 23, 45]

    四、代码逻辑

    • 将此序列均分成两个长度为n/2的子序列
    • 再将每个子序列均分成两个m/2个子序列,直到长度为1
    • 将两个排序好的子序列合并成一个新序列,得到最终序列

    五、代码实现

    function mergeSort(arr) {
        // 序列长度为1时退出
        if (arr.length < 2 ) {
            return arr
        }
    
        // 将序列分为两个子序列,这一块起到“分治法”中的“分割”
        const middle = Math.floor(arr.length/2)
        const left = arr.slice(0, middle)
        const right = arr.slice(middle)
        
        // 递归,这一块起到“分治法”中的“集成”
        return merge(mergeSort(left), mergeSort(right))
    }
    
    function merge(left, right) {
        const result = []
        
        // 两个子序列进行比较,从小到大放入新的序列result中
        while(left.length > 0 && right.length > 0) {
            // 将较小的放入result,并改变left或者right的长度,灵活使用shift方法
            if (left[0] < right[0]) {
                result.push(left.shift())
            } else {
                result.push(right.shift())
            }
        }
        
        // 先将小的元素放入result中,直到left或者right为空,剩余的一个数组肯定是大于result的有序序列,所以直接通过concat进行合并返回
        return result.concat(left, right)
    }
    
    // 测试
    const arr = [12, 2 , 13, 23, 4, 45]
    mergeSort(arr) // [2, 4, 12, 13, 23, 45]
    
  • 相关阅读:
    订单号设计
    小公司的技术架构原则
    Redis配置详解
    实现图片懒加载
    Js的GC机制
    防抖与节流
    Js中的堆栈
    浏览器窗口间通信
    块级格式化上下文
    实现瀑布流布局
  • 原文地址:https://www.cnblogs.com/huiwenhua/p/13633199.html
Copyright © 2020-2023  润新知