zoukankan      html  css  js  c++  java
  • 排序算法——归并排序

    思路

    我学习的归并是简单的二路归并,思路如下:

    ① 将数组平均分成两份

    ② 递归重复①,直到每个数组中只有1个元素,只有一个元素的数组可以认为是排好序的

    ③ 将两个排好序的数组合并成一个排好序的数组

    ④ 重复③直到最终得到一个排好序的数组

    javascript实现

    /**
     * 归并排序
     * @param arr
     * @returns 
     */
    function mergeSort(arr){
        if(!(arr instanceof  Array)){
            return [];
        }
        if(arr.length<=1){
            return arr;
        }
    
        var left=arr.splice(0,Math.floor(arr.length/2)),
            right=arr,
            res=[];
        left=mergeSort(left);
        right=mergeSort(right);
        //一次归并,认为左右两边的数组是排序好的,通过这种方式将它们合成为一个排序好的数组
        //只有一个元素的数组可以认为是已经排序好的,所以通过:
        //left=mergeSort(left);
        //right=mergeSort(right);
        //两步递归得到拆分为一个元素的数组,再通过下面的归并得到结果
        while(left.length && right.length){
            left[0]>right[0] ? res.push(right.shift()): res.push(left.shift());
        }
        //归并剩下的元素都是比res中的大的,直接拼接到后边就好了
        res=res.concat(left,right);
        return res;
    }

    其他

    在一些文章里边看到有人认为浏览器中,采用递归函数调用的方式实现算法有栈溢出的风险。

    因为函数每次调用都会产生一个上下文,放在上下文栈中,执行完毕后才会清除。但是递归调用会导致很多个上下文对象,这样如果待排序的数组过长,在某些浏览器下可能会发生栈溢出的错误。

    测试浏览器上下文栈上限的代码:

    var cnt = 0;
    try {
      (function() {
        cnt++;
        arguments.callee();
      })();
    } catch(e) {
      console.log(e.message, cnt);
    }

    我测试过后发现主流浏览器的上下文栈长度上限都能达到2w左右,在前端一般不会做如此大量数据的排序。

    也可以选择将递归的方式改为迭代的方式来规避这个问题

  • 相关阅读:
    富可视M310刷机包 MIUIV5 红米开发版 闪光 美化 稳定
    Windowsclient SSH 远程连接Windowsserver(PowerShell Server)
    数据结构与算法02--链表基础
    rhadoop linear regression 问题
    奇怪的git代理超时问题
    怎样利用Heartbeat与Floating IP在Ubuntu 14.04上创建高可用性设置
    IVS_原理
    NN入门
    算法体系
    CNN原理
  • 原文地址:https://www.cnblogs.com/tzyy/p/4871442.html
Copyright © 2011-2022 走看看