【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
Merge Sort : 归并排序,把一个大问题分解成若干相同的小问题,解决小问题后,合并小问题结果,最终把大问题解决. 例如要排序数组 originArr = [2, 5, 3, 8, 9, 6, 3, 4, 2] 先把问题分解为排序 leftArr = [2, 5, 3, 8, 9] 和 rightArr = [6, 3, 4, 2]两个小数组,然后合并leftArr和rightArr,当排序leftArr的时候发现问题还是太复杂, 再把leftArr分解为 leftArr1 = [2, 5, 3] 和 rightArr1 = [8, 9] ...以此递归调用,直到 leftArrN = [2]...
//分治法排序
var originArr = [2, 5, 3, 8, 9, 6, 3, 4, 2]
let startTime = new Date().valueOf();
console.info("原始数组:", originArr)
function mergeSort(arr, from, to) {
//寻找合适的分割点
let mid = parseInt((to + from) / 2);
if (to > from) { //如果 to!= from 说明问题还是太复杂,递归调用分解问题
mergeSort(arr, from, mid);
mergeSort(arr, (mid+1), to);
//合并左边已经排好序的,和右边已经排好序的
merge(arr, from, mid, to);
}
}
function merge(arr, from, mid, to) {
let leftArr = [];
let rightArr = [];
//先把arr左边排好序的部分扔到临时数组leftArr中
for(let i=from; i<= mid; i++) {
leftArr.push(arr[i]);
}
//先把arr右边排好序的部分扔到临时数组rightArr中
for(let j=mid+1; j<= to; j++) {
rightArr.push(arr[j]);
}
//合并规则是,每次比较左边和右边最上面的值,把比较小的扔到arr[n]中,当左边没有了或者右边没有了,则把对应的另外一个数组剩下的值依次放入到arr[n]中
let i=0, j=0;
for(let n=from; n<= to; n++) {
//左边数组没有值了,把右边数组剩下的值依次扔到arr[n]中
if (i>= leftArr.length) {
arr[n] = rightArr[j];
j++;
continue;
}
//右边数组没有值了,把左边数组剩下的值依次扔到arr[n]中
if (j >= rightArr.length) {
arr[n] = leftArr[i];
i++;
continue;
}
//如果左边右边数组都有值,把两者比较小的那个扔到arr[n]中
if (leftArr[i] > rightArr[j]) {
arr[n] = rightArr[j];
j++;
} else {
arr[n] = leftArr[i];
i++;
}
}
// console.info(`分隔点:${from}, ${mid}, ${to}, 合并完成后:`, arr)
}
mergeSort(originArr, 0, originArr.length-1);
console.info("最终排序结果:", originArr)
let endDate = new Date().valueOf()
console.info("花费时间:", endDate - startTime)
打印结果:
原始数组: [ 2, 5, 3, 8, 9, 6, 3, 4, 2 ]
最终排序结果: [ 2, 2, 3, 3, 4, 5, 6, 8, 9 ]
花费时间: 36
归并排序的时间复杂度为nlogn
来源:oschina
链接:https://my.oschina.net/u/148994/blog/692221