一、分治算法
1、分治算法:
就是把一个复杂的问题分解两个或更多的相同或相似的子问题,再把子问题分成更小的子问题,直到最后子问题可以简单的直接解决,原问题的解即子问题的解的合并
2、适用情况
2.1、当该问题缩小到一定规模的时候,比如,该数组只有两个元素,这个时候,这个问题就很好解决。
2.2、该问题可以分解为若干规模较小的相同问题。
2.3、分解的问题的答案可以合并为该问题的解。
3、实现分治算法
function fn(arr, from, to) {
if (to - from == 1) {
return { "max": Math.max(arr[from], arr[to]), "min": Math.min(arr[from], arr[to]) }
} else if (to - from == 0) {
return { "max": arr[from], "min": arr[to] }
} else {
let middle = parseInt(from + (to - from) / 2);
let result1 = fn(arr, from, middle);
let result2 = fn(arr, middle + 1, to);
let result = {};
if (result1["max"] > result2["max"]) {
result["max"] = result1["max"];
} else {
result["max"] = result2["max"];
}
if (result1["min"] > result2["min"]) {
result["min"] = result2["min"];
} else {
result["min"] = result1["min"];
}
return result;
}
}
let arr = [34, 5, 6, 7111, 7, 8, 889, 9];
console.log(fn(arr, 0, arr.length - 1));
核心思想是把数组分解到只有一个元素或者两个元素的时候,直接比大小返回,然后递归处理并返回结果。
二、归并算法
归并算法:
将待排序的元素分为大小大致相同的集合, 分别对两个子集合进行排序, 最终排序号的子集合合并为有序集合。运用分治法。
归并排序的步骤:
1、将给定的列表分为两半(如果列表中的元素数为奇数,则使其大致相等)。
2、以相同的方式继续划分子数组,直到只剩下单个元素数组。
3、从单个元素数组开始,合并子数组,以便对每个合并的子数组进行排序。
4、重复第 3 步单元,直到最后得到一个排好序的数组。
function merge(left, right) {
var tmp = [];
while (left.length && right.length) {
if (left[0] < right[0])
tmp.push(left.shift());//将第一个元素删除并返回,即存放到tmp空数组中
else
tmp.push(right.shift());
}
// console.log(tmp)
return sum=tmp.concat(left, right);//比较完毕后合并,然后进行下一次归并判断
// console.log(tmp)
}
function mergeSort(arr) {
if (arr.length === 1)
return arr;
var mid = Math.floor(arr.length / 2);//数组长度减半
var left = arr.slice(0, mid);//左半边新数组
var right = arr.slice(mid);//右半边新数组
return merge(mergeSort(left),mergeSort(right));//将左右继续对半分,直到arr.length/2=1.这样就完成了将所有数组拆分的工作
}
// var arr = [49, 38, 65, 97, 76, 13, 27, 49,21];
// mergeSort(arr);
// console.log(sum)