- 归并排序
思路: 1.分: 把数组分成两半,再递归地对子数组进行“分”操作,直到分成一个单独的数。
2.合: 把两个数合并为有序数组,再对有序数组进行合并,直到所有子数组合并成 一 个完整数组。
操作:合并两个有序数组
- 新建一个空数组res,用于存放最终排序后的数组。
- 比较两个有序数组的头部,较小者出队并推入res中。
- 如果两个数组还有值就重复第二步。
时间复杂度:“分”的时间复杂度是O(logN),“合”的时间复杂度是O(n),总体时间复杂度为 O(nlogN)。
- 快速排序
思路:
分区:从数组中任意选择一个基准,所有比基准小的元素放在基准前面,所有比基准 大的元素放在基准后面。
递归:递归地对基准前后的子数组进行分区操作
Array.prototype.quickSort = function () {
const rec = (arr) => {
if (arr.length === 1) { return arr; }
const left = [];
const right = [];
const mid = arr[0];
for (let i = 1; i < arr.length; i += 1) {
if (arr[i] < mid) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
return [...rec(left), mid, ...rec(right)];
};
const res = rec(this);
res.forEach((n, i) => { this[i] = n });
};const arr = [2, 4, 5, 3, 1];
arr.quickSort();
时间复杂度:分区的时间复杂度是O(n),递归的时间复杂度是O(logN),总体时间复杂度为 O(nlogN)。
- 二分搜索(前提数组得是有序的)
思路:从数组的中间元素开始,如果中间元素正好是目标值,则搜索结束。
如果目标值大于或者小于中间元素,则在大于或者小于中间元素的那一半数组中搜索
int minIndex = 0;
int maxIndex = arr.length - 1;
int midIndex = (minIndex + maxIndex) / 2;
while (true) {
if (arr[midIndex] > 6) {
maxIndex = midIndex - 1;
}
else if (arr[midIndex] < 6)
{
minIndex = midIndex + 1;
}
else {
break;
}
if (minIndex > maxIndex)
{
midIndex = -1;
break;
}
midIndex = (minIndex + maxIndex) / 2;}
时间复杂度:每一次比较都使搜索范围缩小一半,时间复杂度为O(logN)。