今天主要复习最基本的三大排序,平均时间复杂度 O(n^2^), 本文排序默认按升序处理。
冒泡排序
思路
两重循环,最深的循环,一趟将一个最大的数放到 无序数组末尾,完成一趟无序部分的长度就从尾端减掉1位。
比较第一个数和第二个数,index = 1下标放大的数。
比较第二个数和第三个数,index = 2下标放大的数。
比较第三个数和第四个数,index = 3下标放大的数。
...
不断交换后就会把最大的数放到无序部分末端。
参考代码
function bubbleSort(array) {
for (let i = 0; i < array.length; i++) {
for (let j = 0; j < array.length - 1 - i; j++) {
if (j !== array.length - 1 && array[j] > array[j + 1]) {
[array[j], array[j + 1]] = [array[j + 1], array[j]];
}
}
}
}
注意事项
- 因为有序部分位于数组最后,所以内层循环
j在写边界条件时应只遍历到array.length - 1 - i处,array.length - 1是数组最后一位,i每多遍历1次j就少遍历一个数。
平均时间复杂度: O(n^2^)
选择排序
思路
选择排序顾名思义,选择某个特定的数并交换位置。我们每趟挑选出无序部分的最小的数,然后将最小的数与无序部分第一个数交换数值。
有序部分位于数组开始。
参考代码
function selectSort(array) {
let len = array.length;
for (let i = 0; i < len; i++) {
let minIndex = i;
min = array[i];
for (let j = i; j < len; j++) {
if (array[j] < min) {
min = array[j];
minIndex = j;
}
}
[array[minIndex], array[i]] = [array[i], array[minIndex]];
}
}
注意事项 保存的最小值与其对应的下标初始化时,用无序部分第一个数为其赋值。
平均时间复杂度: O(n^2^),寻找最小数n,要寻找n次,最终n*n;
插入排序
思路
待排序部分第一个数,从已排序部分最后开始遍历,找到第一个小于等于它的数就放在它后面。
参考代码
function insertSort(array) {
for (let i = 0; i < array.length; i++) {
let curr = array[i];
for (let j = i; j >= 0; j--) {
if (j > 0 && array[j - 1] > curr) {
array[j] = array[j - 1];
} else {
array[j] = curr;
break;
}
}
}
return array;
}
注意事项
- 找到后赋值后,记得加break结束循环。
- 找比它小的数时使用
j - 1索引,这样小于等于它时就直接给j赋值。
平均时间复杂度: O(n^2^),寻找最小数n,要寻找n次,最终n*n;