算法:归并排序

归并排序算法,先看以下一张图:
归并排序逻辑图
结合图片看过程:

  1. 从上往下,把数组1/2等分,然后再1/2等分。。。
  2. 从下往上,在合并的时候,会对等分的数组进行比较,用上图的Level 1说明:
    左侧是[i,mid],右侧是[j,right],上级的是[left,right]
    首先,i索引 位置的值和 j索引 位置的值比较,小的值放到 k索引 的位值,小的值的 索引 自增,k索引 自增
    有一种临界情况,当 i>mid ,或者 j>right,说明等分数组有一边已经遍历完成,遍历完成的数组之后不再需要自增了,k的值取没有完成遍历的

看具体实现代码:
sortMerge.js

// 归并排序
window.sortMerge = {
    _mergeSort(arr,l,mid,r) {
        var tmp = [];
        for (var i=l; i<=r; i++) {
            tmp.push(arr[i]);
        }
        //
        for (var i=l,j=mid+1,k=l; k<=r; k++) {
            if (i>mid) {
                arr[k] = arr[j];
                j++;
            } else if (j>r) {
                arr[k] = arr[i];
                i++;
            } else if (arr[i]<arr[j]) {
                arr[k] = arr[i];
                i++;
            } else {
                arr[k] = arr[j];
                j++;
            }
        }
    },
    _merge(arr,l,r) {
        let mid = Math.floor((l+r)/2);
        // if (l>=mid) return;
        // 数组足够小,用插入排序
        if (r-l<=10) {
            sortBasic.insert_limit({arr,l,r});
            return;
        }
        sortMerge._merge(arr, l, mid);
        sortMerge._merge(arr, mid+1, r);
        // 优化,两边都排序完成,mid<=mid+1的值,不需要执行
        if (arr[mid]>arr[mid+1]) {
            sortMerge._mergeSort(arr,l,mid,r);
        }
    },
    merge({arr, orderby="asc"}) {
        sortMerge._merge(arr, 0, arr.length-1);
        return arr;
    },
    mergeBU({arr, n}) {
        n = n ? n : arr.length-1;
        for (var sz=1; sz<=n; sz+=sz) {
            for (var i=0; i+sz<n; i+=sz+sz) {
                sortMerge._mergeSort(arr, i, i+sz-1, Math.min(i+sz+sz-1, n-1));
            }
        }
        return arr;
    }
}

test.js 追加(请先看算法-基础篇)

let {
    merge,
} = sortMerge;
// test4 插入排序vs并归排序,并归效率非常高
// testSort({arr:arr1, fn:insert});
// testSort({arr:arr2, fn:merge});

//test5 插入排序vs并归排序,数据源接近有序的:效率都非常高,插入排序相对用时少些
// testSort({arr:arr3, fn:insert});
// testSort({arr:arr4, fn:merge});

mergeBU方法和_merge方法接近,区别是自底而上。
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值