关于算法--分治法--合并排序

分治法:

1、思想:①将问题的实例划分为同一个问题的几个较小的实例,最好拥有相同的规模;②对于较小的实例进行求解,一般使用递归法,在问题规模足够小的情况下也是用另一个算法;③如果必要的话,合并这些较小问题的解

2、通用分治递推式:T(n) = a*T(n/b) + f(n); 其中,T(n)是指运算次数

3、主定律:上式中的f(n)是属于Θ(nd),d≥0,则:

当a<bd时,T(n)属于Θ(nd);

当a=bd时,T(n)属于Θ(n* log n);

当a>bd时,T(n)属于Θ(nlogba)


合并排序

一、步骤

a.  1、输入一个可排序数组arr,如果其规模大于1,则将其分为两个规模基本相同的子数组_arr1,_arr2

   2、对子数组分别重新调用本函数

   3、递归调用完毕后,调用b方法,对有序数组进行合并

b. 1、输入为两个有序数组arr1,arr2以及一个存储容器arr3

  2、对arr1 arr2内的元素进行比对,小的赋值给arr3,并将大的与下一个比较

    3、若其中有一个比较完毕,则将另外一个剩下的数字依次赋值到数组尾部

 

二、JavaScript代码实现

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>合并排序法</title>
</head>
<body>
    
</body>
<script type="text/javascript">
    var mergesort = function(arr) {
        var n = arr.length;
        if (n > 1) {
            //将数组平均分为两个子数组
            var _arr1 = arr.slice(0, Math.floor(n/2));    
            var _arr2 = arr.slice(Math.ceil(n/2), n);

            //对子数组重新调用本方法
            mergesort(_arr1);
            mergesort(_arr2);

            //实现两个有序数组的合并
            merge(_arr1, _arr2, arr);

            //返回排过序的结果
            return arr;
        }else{
            return arr;
        }
    }

    /**
     * 实现对两个有序数组的合并
     * @param  {Array} arr1 有序数组
     * @param  {Array} arr2 有序数组
     * @param  {Array} arr3 
     * @return {[Array]}     [arr1与arr2两者合并后的顺序数组]
     */
    function merge(arr1, arr2, arr3) {
        var i = 0, j = 0, k = 0, p = arr1.length, q = arr2.length;
        //当两个数组的元素依次比对,小的元素赋值给arr3
        while(i < p && j < q){
            if(arr1[i] < arr2[j]){
                arr3[k] = arr1[i];
                i++;
            }else{
                arr3[k] = arr2[j];
                j++;
            }
            k++;
        }

        //肯定是一个数组比对完毕,另一个数组未完全用完,因此该数组剩下的数字添加到arr3中
        if (i == p ) {    //如果arr2未处理完
            for(;j < q; j++){
                arr3[k] = arr2[j];
                k++;
            }
        } else {        //如果arr1未处理完
            for(;i < p; i++){
                arr3[k] = arr1[i];
                k++;
            }
        }
    };
    console.log(mergesort([8,3,2,9,7,1,5,4]));    
</script>
</html>

三、算法分析

若输入规模是2的乘方,则键值的比较次数C(n) = 2C(n/2) + Cmerge(n), C(1) = 0;其中Cmerge(n)是合并阶段的键值比较次数。

最差的情况下,Cmerge(n) = n - 1;此时,C(n) = 2C(n/2) + n - 1;因此根据主定律C(n)属于Θ(n logn);  Cworst = nlog2n - n + 1

 

posted @ 2016-07-19 20:57  李靠谱  阅读(1065)  评论(0)    收藏  举报