zoukankan      html  css  js  c++  java
  • 【拿下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]
    
  • 相关阅读:
    Maximum sum-动态规划
    Ubuntu14下Hadoop开发&lt;1&gt; 基础环境安装
    POJ 3252 Round Numbers 数学题解
    ubuntu环境 rake aborted!
    oracle decode函数用法
    Android多线程研究(1)——线程基础及源码剖析
    2014冬去春来
    Android中的动画详解系列【4】——Activity之间切换动画
    JavaScript你所不知道的困惑(3)
    研发人员技术定级的一些思考
  • 原文地址:https://www.cnblogs.com/huiwenhua/p/13633199.html
Copyright © 2011-2022 走看看