1. 合并算法
归并排序最核心的思路是,两个有序列表合并,只需要各循环一次,就可以将两个有序列表合并成一个有序列表。比如[1,4]和[2,3],1和2比较,将1放在temp数组中,4和2比较,将2放在temp中,4和3比较,将3放在temp中,最后将4放在temp中
先写合并的算法。
function merge(li, start, mid, end) {
let left = start,
right = mid + 1,
tempList = [];
while (left <= mid && right <= end) {
if (li[left] < li[right]) {
tempList.push(li[left]);
left++;
} else {
tempList.push(li[right]);
right++;
}
}
while (left <= mid) {
tempList.push(li[left]);
left++;
}
while (right <= end) {
tempList.push(li[right]);
right++;
}
for (let index = 0; index < tempList.length; index++) {
li[start + index] = tempList[index]
}
}
2. 拆分
这里有一个前提就是,两个数组必需是有序数组,所以需要将原数组拆分,最终分成只有一个元素的时候,自然就是有序的,然后再逐层将数组合并。
function merge(li, start, mid, end) {
let left = start,
right = mid + 1,
tempList = [];
while (left <= mid && right <= end) {
if (li[left] < li[right]) {
tempList.push(li[left]);
left++;
} else {
tempList.push(li[right]);
right++;
}
}
while (left <= mid) {
tempList.push(li[left]);
left++;
}
while (right <= end) {
tempList.push(li[right]);
right++;
}
for (let index = 0; index < tempList.length; index++) {
li[start + index] = tempList[index]
}
}
function mergeSort(li, start, end) {
if (start < end) {
let mid = Math.floor((start + end) / 2);
mergeSort(li, start, mid);
mergeSort(li, mid + 1, end);
merge(li, start, mid, end);
}
return li;
}
let testLi = new Array(99);
for (let index = 0; index < testLi.length; index++) {
testLi[index] = Math.ceil(Math.random() * 100)
}
console.log(testLi);
mergeSort(testLi, 0, testLi.length - 1)
console.log(testLi);
3.算法分析
归并算法时间复杂度为O(nlogn),而且和原数组的顺序没有关系,所以时间复杂度很稳定,空间复杂度为O(n)