冒泡排序:
时间:最好 O(n), 平均 O(n^2), 最差 O(n^2)
空间:O(1)
function bubbleSort(arr) {
// n 个数字需要最多需要遍历 n - 1 轮
for (let i = 0; i < arr.length - 1; i++) {
// swapped 优化遍历轮数,一轮中没有交换元素说明排序已完成
let swapped = false;
// 优化比较次数:每一轮至少一个元素冒泡到最后,该元素下一轮无需比较,所以每轮比较 n - 1 - i 次
for (let j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr, j, j + 1);
swapped = true;
}
}
if (swapped === false) {
break;
}
}
return arr;
}
function swap(arr, i, j) {
let temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
插入排序
时间:最好 O(n), 平均 O(n^2), 最差 O(n^2)
空间: O(1)
function insertionSort(arr) {
if (!arr || arr.length < 2) return arr;
// 默认第一个元素已排好序,从第二个元素开始遍历
for (let i = 1; i < arr.length; i++) {
// 把当前元素插入到该元素左边已排好序的数组里
// arr[i] = valueToInsert
for (let j = i - 1; j >= 0; j--) {
if (arr[j] > arr[j + 1]) {
swap(arr, j, j + 1);
} else {
break;
}
}
}
return arr;
}
选择排序
时间:最好 O(n^2), 平均 O(n^2), 最差 O(n^2)
空间:O(1)
function selectionSort(arr) {
if (!arr || arr.length < 2) return arr;
for (let i = 0; i < arr.length - 1; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[i]) {
swap(arr, i, j);
}
}
}
return arr;
}
并归排序
时间:最好 O(n log(n)), 平均 O(n log(n)), 最差 O(n log(n))
空间:O(n)
function mergeSort(arr, start, end) {
if (!arr || arr.length < 2) return arr;
if (start >= end) return;
const mid = Math.floor((start + end) / 2);
mergeSort(arr, start, mid);
mergeSort(arr, mid + 1, end);
merge(arr, start, mid, end);
return arr;
}
function merge(arr, start, mid, end) {
let result = [];
let i = 0;
let p1 = start;
let p2 = mid + 1;
while (p1 <= mid && p2 <= end) {
if (arr[p1] < arr[p2]) {
result[i++] = arr[p1++];
} else {
result[i++] = arr[p2++];
}
}
while (p1 <= mid) {
result[i++] = arr[p1++];
}
while (p2 <= end) {
result[i++] = arr[p2++];
}
for (i = 0; i < result.length; i++) {
arr[start + i] = result[i];
}
}
快速排序
时间:最好 O(n log(n)), 平均 O(n log(n)), 最差 O(n^2)
空间:O(log(n))
function quickSort(arr, left, right) {
if (!arr || arr.length < 2) return arr;
if (left < right) {
let pi = partition(arr, left, right);
quickSort(arr, left, pi - 1);
quickSort(arr, pi + 1, right);
}
return arr;
}
function partition(arr, left, right) {
let pivot = arr[right];
// i keeps track of value smaller than pivot
let i = left - 1;
for (let j = left; j < right; j++) {
if (arr[j] < pivot) {
// makes all numbers right to i are smaller than pivot
i++;
// swap i with latest small value
swap(arr, i, j);
}
}
// swap i + 1 with pivot
swap(arr, i + 1, right);
return i + 1;
}