核心思想
分治:将问题分成一些小的问题然后递归求解,治则将分的阶段得到的各答案"修补"在一起
- 分
把原数组划分成两个子数组 - 治
将两个有序数组合并成一个更大的有序数组
步骤
- 将数组平均分成两个子数组,再递归将子数组也分割成两个更小的子数组
- 当数组中只有一个元素时可以视为有序数组,开始合并操作
- 设置两个指针,
i
指向前一个数组的第一个元素,j
指向后一个数组的第一个元素;设置一个数组temp
用来存储排序后的数组 - 比较
arr[i]
和arr[j]
,谁更小就将谁存入temp
并移动该指针,例如:arr[i] < arr[j]
,则将arr[i]
存入temp
,并且i++
- 如果一个子数组的元素全部存完,则将另一子数组的剩余元素全部存到
temp
中 - 最后将
temp
元素中的内容拷贝到原数组即可
代码(js)
function mergeSort(begin, end) //分
{
if(begin == end) //数组中只剩一个元素则分阶段完毕
return;
var mid = (begin+end) >> 1; //左右数组分界点,指向左数组最后一个元素
mergeSort(begin, mid); //继续划分左数组
mergeSort(mid+1, end); //继续划分右数组
merge(begin, end, mid); //排序合并
}
function merge(begin, end, mid) //治
{
var i = begin; //指向左数组第一个元素
var j = mid+1; //指向右数组第一个元素
var temp = [];
while(i <= mid && j <= end){
if(arr[i] <= arr[j]){
temp.push(arr[i]);
i++;
}
else{
temp.push(arr[j]);
j++;
}
}
//将左或右数组中剩余元素全部放到temp中
while(i <= mid){
temp.push(arr[i]);
i++;
}
while(j <= end){
temp.push(arr[j]);
j++;
}
//将temp元素拷贝到原数组
var t = 0;
while(begin <= end){
arr[begin] = temp[t];
begin++;
t++;
}
}