码迷,mamicode.com
首页 > 编程语言 > 详细

排序算法——归并排序

时间:2015-10-12 14:29:43      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:

思路

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

① 将数组平均分成两份

② 递归重复①,直到每个数组中只有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左右,在前端一般不会做如此大量数据的排序。

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

排序算法——归并排序

标签:

原文地址:http://www.cnblogs.com/tzyy/p/4871442.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!