十大排序算法
| 排序算法 | 平均时间复杂度 | 最坏时间复杂度 | 最好时间复杂度 | 空间复杂度 | 稳定性 |
|---|
| 冒泡排序(Bubble Sort) | O(n^2) | O(n^2) | O(n) | O(1) | 稳定 |
| 选择排序(Selection Sort) | O(n^2) | O(n^2) | O(n^2) | O(1) | 不稳定 |
| 插入排序(Insertion Sort) | O(n^2) | O(n^2) | O(n) | O(1) | 稳定 |
| 希尔排序(Shell Sort) | 取决于间隔序列 | 取决于间隔序列 | 取决于间隔序列 | O(1) | 不稳定 |
| 归并排序(Merge Sort) | O(n log n) | O(n log n) | O(n log n) | O(n) | 稳定 |
| 快速排序(Quick Sort) | O(n log n) | O(n^2) | O(n log n) | O(log n)~O(n) | 不稳定 |
| 堆排序(Heap Sort) | O(n log n) | O(n log n) | O(n log n) | O(1) | 不稳定 |
| 计数排序(Counting Sort) | O(n + k) | O(n + k) | O(n + k) | O(k) | 稳定 |
| 桶排序(Bucket Sort) | O(n + k) | O(n^2) | O(n) | O(n + k) | 稳定 |
| 基数排序(Radix Sort) | O(k * n) | O(k * n) | O(k * n) | O(n + k) | 稳定 |
冒泡排序
function bubbleSort(arr: number[]): number[] {
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length - i; j++) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
}
}
}
return arr;
}
选择排序
function selectSort(arr: number[]): number[] {
for (let i = 0; i < arr.length; i++) {
let maxNumIndex = 0;
for (let j = 1; j < arr.length - i; j++) {
if (arr[j] > arr[maxNumIndex]) {
maxNumIndex = j;
}
}
[arr[maxNumIndex], arr[arr.length - i - 1]] = [
arr[arr.length - i - 1],
arr[maxNumIndex],
];
}
return arr;
}
插入排序
const insertSort = (arr: number[]): number[] => {
for (let i = 1; i < arr.length; i++) {
let preIndex = i - 1;
let nextIndex = i;
while (arr[nextIndex] < arr[preIndex] && preIndex >= 0) {
[arr[nextIndex], arr[preIndex]] = [arr[preIndex], arr[nextIndex]];
nextIndex--;
preIndex--;
}
}
return arr;
};
希尔排序
const insertSortByStep = (
arr: number[],
offset: number,
step: number
): number[] => {
for (let i = step + offset; i < arr.length; i = i + step) {
let nextIndex = i;
let preIndex = nextIndex - step;
while (arr[nextIndex] < arr[preIndex] && preIndex >= offset) {
[arr[preIndex], arr[nextIndex]] = [arr[nextIndex], arr[preIndex]];
nextIndex -= step;
preIndex -= step;
}
}
return arr;
};
const shellSort = (arr: number[]): number[] => {
for (
let step = Math.round(arr.length / 2);
step > 0;
step = Math.floor(step / 2)
) {
for (let offset = 0; offset < step; offset++) {
insertSortByStep(arr, offset, step);
}
}
return arr;
};
归并排序
const merge = (left: number[], right: number[]) => {
let i = 0;
let j = 0;
const res: number[] = [];
while (i < left.length && j < right.length) {
if (left[i] < right[j]) {
res.push(left[i]);
i++;
} else {
res.push(right[j]);
j++;
}
}
while (i < left.length) {
res.push(left[i]);
i++;
}
while (j < right.length) {
res.push(right[j]);
j++;
}
return res;
};
const mergeSort = (arr: number[]): number[] => {
if (arr.length <= 1) {
return arr;
}
const mid = Math.floor(arr.length / 2);
const leftArr = arr.slice(0, mid);
const rightArr = arr.slice(mid);
const left = mergeSort(leftArr);
const right = mergeSort(rightArr);
return merge(left, right);
};
快速排序
export const quickSort = (arr: number[]): number[] => {
if (arr.length <= 1) return arr;
const val = arr[0];
const left: number[] = [];
const right: number[] = [];
for (let i = 1; i < arr.length; i++) {
arr[i] < val ? left.push(arr[i]) : right.push(arr[i]);
}
return [...quickSort(left), val, ...quickSort(right)];
};
const quickSortPlus = (
arr: number[],
start: number = 0,
end: number = arr.length - 1
) => {
if (end - start < 1) return arr;
const val = arr[start];
let idx = start;
for (let i = start + 1; i <= end; i++) {
if (arr[i] < val) {
const temp = arr[i];
let j = i;
while (j > start) {
arr[j] = arr[j - 1];
j--;
}
arr[start] = temp;
idx++;
}
}
quickSortPlus(arr, start, idx - 1);
quickSortPlus(arr, idx + 1, end);
return arr;
};
堆排序
const heapify = (arr: number[], i: number, len: number) => {
const left = 2 * i + 1;
const right = 2 * i + 2;
let largest = i;
if (left < len && arr[left] > arr[largest]) {
largest = left;
}
if (right < len && arr[right] > arr[largest]) {
largest = right;
}
if (largest !== i) {
[arr[i], arr[largest]] = [arr[largest], arr[i]];
heapify(arr, largest, len);
}
};
const buildMaxHeap = (arr: number[]): number[] => {
const len = arr.length;
for (let i = Math.floor(arr.length / 2); i >= 0; i--) {
heapify(arr, i, len);
}
return arr;
};
const heapSort = (arr: number[]): number[] => {
buildMaxHeap(arr);
for (let i = arr.length - 1; i > 0; i--) {
[arr[0], arr[i]] = [arr[i], arr[0]];
heapify(arr, 0, i);
}
return arr;
};
计数排序
const countSort = (arr: number[]): number[] => {
let min = arr[0];
let max = arr[0];
for (let i = 0; i < arr.length; i++) {
const cur = arr[i];
if (cur < min) {
min = cur;
}
if (cur > max) {
max = cur;
}
}
const newArr = new Array(max - min + 1).fill(0);
for (let i = 0; i < arr.length; i++) {
const cur = arr[i];
newArr[cur - min]++;
}
const res: number[] = [];
for (let i = 0; i < newArr.length; i++) {
let cur = newArr[i];
while (cur > 0) {
res.push(i + min);
cur--;
}
}
return res;
};
桶排序
const bucketSort = (arr: number[]): number[] => {
let max = arr[0];
let min = arr[0];
for (let i = 0; i < arr.length; i++) {
if (max < arr[i]) max = arr[i];
if (min > arr[i]) min = arr[i];
}
const d = max - min;
const bucketNum = 10;
const bucketArr: number[][] = [];
for (let i = 0; i <= bucketNum; i++) {
bucketArr[i] = [];
}
for (let i = 0; i < arr.length; i++) {
const index = Math.floor(((arr[i] - min) / d) * bucketNum);
bucketArr[index].push(arr[i]);
}
const res = bucketArr.map((item) => quickSort(item)).flat();
return res;
};
const quickSort = (arr: number[]): number[] => {
if (arr.length <= 1) return arr;
const val = arr[0];
const left: number[] = [];
const right: number[] = [];
for (let i = 1; i < arr.length; i++) {
arr[i] < val ? left.push(arr[i]) : right.push(arr[i]);
}
return [...quickSort(left), val, ...quickSort(right)];
};
基数排序