| 排序算法 | 时间复杂度(平均) | 时间复杂度(最差) | 时间复杂度(最好) | 空间复杂度 | 排序方式 | 稳定性 |
|---|
| 冒泡排序 | O(n^2) | O(n^2) | O(n) | O(1) | 内部排序 | 稳定 |
| 选择排序 | O(n^2) | O(n^2) | O(n^2) | O(1) | 内部排序 | 不稳定 |
| 插入排序 | O(n^2) | O(n^2) | O(n) | O(1) | 内部排序 | 稳定 |
| 希尔排序 | O(nlogn) | O(nlogn) | O(nlogn) | O(1) | 内部排序 | 不稳定 |
| 归并排序 | O(nlogn) | O(nlogn) | O(nlogn) | O(n) | 外部排序 | 稳定 |
| 快速排序 | O(nlogn) | O(n^2) | O(nlogn) | O(logn) | 内部排序 | 不稳定 |
| 堆排序 | O(nlogn) | O(nlogn) | O(nlogn) | O(1) | 内部排序 | 不稳定 |
| 计数排序 | O(n+k) | O(n+k) | O(n+k) | O(k) | 外部排序 | 稳定 |
| 桶排序 | O(n+k) | O(n^2) | O(n+k) | O(n+k) | 外部排序 | 稳定 |
| 基数排序 | O(n*k) | O(n*k) | O(n*k) | O(n+k) | 外部排序 | 稳定 |
function swap(arr, i, j) {
[arr[i], arr[j]] = [arr[j], arr[i]];
}
function selectSort(arr) {
for (let i = 0; i < arr.length - 1; ++i) {
let minPos = i;
for (let j = i + 1; j < arr.length; ++j) {
if (arr[j] < arr[minPos]) minPos = j;
}
swap(arr, i, minPos);
}
return arr;
}
function bubbleSort(arr) {
for (let i = arr.length - 1; i >= 1 ; --i) {
let flag = true;
for (let j = 0; j < i; ++j) {
if (arr[j] > arr[j + 1]) {
swap(arr, j, j + 1);
flag = false;
}
}
if (flag) break;
}
return arr;
}
function insertSort(arr) {
for (let i = 1; i < arr.length; ++i) {
let tmp = arr[i];
let j = i - 1;
while (j >= 0 && tmp < arr[j]) {
arr[j + 1] = arr[j];
--j;
}
arr[j + 1] = tmp;
}
return arr;
}
function quickSort(arr) {
if (arr.length <= 1) return arr;
let pivot = arr[0];
let left = [], right = [];
for (let i = 1; i < arr.length; ++i) {
if (arr[i] < pivot) left.push(arr[i]);
else right.push(arr[i]);
}
return quickSort(left).concat(pivot, quickSort(right));
}
function shellSort(arr) {
let gap = 1;
while (gap < arr.length / 3) gap = gap * 3 + 1;
for (gap; gap > 0; gap = Math.floor(gap/3)) {
for (let i = gap; i < arr.length; ++i) {
let tmp = arr[i];
let j;
for (j = i - gap; j >= 0 && arr[j] > tmp; j -= gap) {
arr[j + gap] = arr[j];
}
arr[j + gap] = tmp;
}
}
return arr;
}
function merge(left, right) {
let res = [];
while (left.length > 0 && right.length > 0) {
if (left[0] < right[0]) res.push(left.shift());
else res.push(right.shift());
}
return res.concat(left, right);
}
function mergeSort(arr) {
if (arr.length == 1) return arr;
let mid = Math.floor(arr.length / 2);
let left = arr.slice(0, mid);
let right = arr.slice(mid);
return merge(mergeSort(left), mergeSort(right))
}
function shiftDown(arr, i, length) {
for (let j = 2*i+1; j < length; j = 2*j+1) {
let tmp = arr[i];
if (j + 1 < length && arr[j] < arr[j + 1]) ++j;
if (tmp < arr[j]) {
swap(arr, i, j);
i = j;
} else break;
}
}
function heapSort(arr) {
for (let i = Math.floor(arr.length / 2); i >= 0; --i) {
shiftDown(arr, i, arr.length);
}
for (let j = arr.length - 1; j > 0; --j) {
swap(arr, 0, j);
shiftDown(arr, 0, j);
}
return arr;
}
function bucketSort(arr, num) {
let max = Math.max.apply(null, arr),
min = Math.min.apply(null, arr);
let buckets = [],
bucketSize = Math.floor((max-min+1) / num);
for (let i = 0; i < arr.length; ++i) {
let index = ~~(arr[i] / bucketSize);
!buckets[index] && (buckets[index] = []);
buckets[index].push(arr[i]);
let len = buckets[index].length;
while (len > 0) {
(buckets[index][len-1] > buckets[index][len]) && ([buckets[index][len], buckets[index][len-1]] = [buckets[index][len-1], buckets[index][len]]);
--len;
}
};
let wrapBuckets = [];
for (let i = 0; i < buckets.length; ++i) {
buckets[i] && (wrapBuckets = wrapBuckets.concat(buckets[i]));
}
return wrapBuckets;
}
function countSort(arr) {
let max = Math.max.apply(null, arr);
let res = [];
let tmp = new Array(max+1).fill(0);
for (let item of arr) {
++tmp[item];
}
for (let index in tmp) {
while (tmp[index]-- > 0) res.push(+index);
}
return res;
}
function getLoopTimes(num) {
return (num+"").split("").length;
}
function getBucketNumber(num, d) {
return (num+"").split("").reverse()[d];
}
function lsdRadixSort(arr, buckets, radix) {
for (let i = 0; i < arr.length; ++i) {
let ele = arr[i];
let index = getBucketNumber(ele, radix);
buckets[index].push(ele);
}
let k = 0;
for (let i = 0; i < 10; ++i) {
let bucket = buckets[i];
for (let j = 0; j < bucket.length; ++j) {
arr[k++] = bucket[j];
}
}
}
function radixSort(arr) {
let max = Math.max.apply(null, arr),
times = getLoopTimes(max),
len = arr.length;
let buckets = [];
for (let i = 0; i < 10; ++i) {
buckets[i] = [];
}
for (let radix = 0; radix < times; ++radix) {
lsdRadixSort(arr, buckets, radix);
}
return arr;
}