排序算法
冒泡排序
冒泡排序就是从序列中的第一个元素开始,依次对相邻的两个元素进行比较,看是否满足大小关系要求,如果不满足就交换两个元素的位置。一次冒泡会让至少一个元素移动到它应该在的位置,重复 n 次,就完成了 n 个数据的排序工作
时间复杂度:O(N²)。【因为有2个循环】
空间复杂度:O(1)。
function bubbleSort(array) {
const len = array.length;
let i = 0;
// 每轮循环都是从第一个元素开始, 循环len 次
while (i < len) {
// 每一次循环,结尾多一个排好序的元素,每次结尾都少遍历一个
const lastIndex = len - 1 - i;
i++;
for (let j = 0; j < lastIndex; j++) {
// 当前元素与下一个元素做比较,如果大于的话调换顺序
if (array[j] > array[j + 1]) {
[array[j], array[j + 1]] = [array[j + 1], array[j]];
}
}
}
return array;
}
选择排序
在数组中先找出最小数的索引(最初假设第一个元素为最小值),设一个变量保存下来,把最小的元素放在数组最前面,重复前面的步骤,将最小值放在前一个最小值后面
时间复杂度:O(N²)。
空间复杂度:O(1)。
function selectSort(arr) {
let len = arr.length;
for(let i = 0; i < len; i++) {
let minIndex = i;
for(let j = i + 1; j < len; j++) {
if(arr[j] < arr[minIndex]) minIndex = j;
}
[arr[i], arr[minIndex]] = [arr[minIndex], arr[i]]
}
return arr
}
插入排序
将第一个元素认为是一个有序数列,剩下的为无序数列,从第二个元素开始遍历,取无序数列中第一个元素跟有序数列元素比较(从最后面元素开始),若比有序数列小,有序数列元素往后挪移一位,直到比有序数列元素大,此时有序数列空一个位置,将当前值插入有序数列
时间复杂度:O(N²)。
空间复杂度:O(1)。
function insertionSort(array) {
const len = array.length;
// 从第二个开始遍历
for (let i = 1; i < len; i++) {
// 获取当前值
const curValue = array[i];
let j = i - 1;
// 遍历 i 之前的元素,如果大于curValue,则直接往后挪一位
while (j >= 0 && array[j] > curValue) {
array[j + 1] = array[j];
j--;
}
// 插入 curValue
array[j + 1] = curValue;
}
return array;
}
快速排序
方式一:
取一个基准数,剩下元素逐个跟其比较,小的放一个数组,大的放另一个数组,再对两个数组做同样操作直至排序完成,拼接基准数和两个数组。
劣:该种方式内存消耗多
function quickSort( arr ) {
if(arr.length <= 1) return arr;
const num = arr[0];
let left = [], right = [];
for(let i = 1;i < arr.length; i++) {
if(arr[i]<=num) left.push(arr[i]);
else right.push(arr[i]);
}
console.log(left, right)
return quickSort(left).concat([num],quickSort(right));
}
var arr = [2,4,6,1,0,9,8]
quickSort(arr)
方式二:
function quickSort(arr, start, end) {
function swap(arr, i, k) {
let temp = arr[i];
arr[i] = arr[k];
arr[k] = temp;
}
// 数组分区,左小右大
function partition(arr, left, right) {
let storeIndex = left;
let pivot = arr[right]; // 直接选最右边的元素为基准元素
for(let i = left; i < right; i++) {
if(arr[i] < pivot) {
swap(arr, storeIndex, i); //将比基准元素大的跟比基准元素小的换位置
storeIndex++; // 交换位置后,storeIndex 自增 1,代表下一个可能要交换的位置
}
}
swap(arr, storeIndex, right); // 将基准元素放置到最后的正确位置上
return storeIndex;
}
function sort(arr, left, right) {
if(left > right) {
return;
}
let storeIndex = partition(arr, left, right);
sort(arr, left, storeIndex - 1);
sort(arr, storeIndex + 1, right);
}
sort(arr, start, end);
return arr;
}
quickSort([3,7,8,5,2,1,9,5,4], 3, 7) // 只对部分元素排序