时间复杂度 空间复杂度
类别 排序方法 平均情况 最好情况 最坏情况 辅助存储 稳定性
插入类 直接插入 O(n^2) O(n) O(n^2) O(1) 稳定
排序 shell排序 O(n^1.3~2) O(n) O(n^2) O(1) 不稳定 .
选择类 直接选择 O(n^2) O(n^2) O(n^2) O(1) 不稳定
排序 堆排序 O(nlogn) O(nlogn) O(nlogn) O(1) 不稳定 .
交换类 冒泡排序 O(n^2) O(n) O(n^2) O(1) 稳定
排序 快速排序 O(nlogn) O(nlogn) O(n^2) O(logn) 不稳定 .
归并排序 O(nlogn) O(nlogn) O(nlogn) O(n) 稳定
基数排序 O(d(r+n)) O(d(n+rd)) O(d(r+n)) O(rd+n) 稳定
r是关键字的基数,d是长度,n是关键字的个数
插入排序 时间复杂度 平均 O(n^2) 最好 O(n) 最坏 O(n^2) 空间复杂度 O(1) 稳定
public void insertSort(int[] arr) {
int value, j;
for (int i = 1; i < arr.length; i++) {
value = arr[i];
for (j = i - 1; j >= 0 && value < arr[j]; j--) {
arr[j + 1] = arr[j];
}
arr[j + 1] = value;
}
}
希尔排序 时间复杂度 平均 O(n^1.3~2) 最好 O(n) 最坏 O(n^2) 空间复杂度 O(1) 不稳定
public void shellSort(int[] arr) {
int j, temp;
for (int gap = arr.length / 2; gap > 0; gap /= 2) {
for (int i = gap; i < arr.length; i++) {
j = i;
temp = arr[j];
if (temp < arr[j - gap]) {
while (j - gap >= 0 && temp < arr[j - gap]) {
arr[j] = arr[j - gap];
j -= gap;
}
arr[j] = temp;
}
}
}
}
选择排序 时间复杂度 平均 O(n^2) 最好 O(n^2) 最坏 O(n^2) 空间复杂度 O(1) 不稳定
public void selectSort(int[] arr) {
int min, minIndex;
for (int i = 0; i < arr.length; i++) {
min = arr[i];
minIndex = i;
for (int j = i + 1; j < arr.length; j++) {
if (min > arr[j]) {
min = arr[j];
minIndex = j;
}
}
if (minIndex != i) {
arr[minIndex] = arr[i];
arr[i] = min;
}
}
}
堆排序 时间复杂度 平均 O(nlog(n)) 最好 O(nlog(n)) 最坏 O(nlog(n)) 空间复杂度 O(1) 不稳定
public void heapSort(int[] arr) {
for (int i = arr.length / 2 - 1; i >= 0; i--) {
adjustHeap(arr, i, arr.length);
}
for (int j = arr.length - 1; j > 0; j--) {
int temp = arr[j];
arr[j] = arr[0];
arr[0] = temp;
adjustHeap(arr, 0, j);
}
}
public void adjustHeap(int[] arr, int i, int length) {
int temp = arr[i];
for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {
if (k + 1 < length && arr[k] < arr[k + 1]) {
k++;
}
if (temp < arr[k]) {
arr[i] = arr[k];
i = k;
} else {
break;
}
arr[i] = temp;
}
}
冒泡排序 时间复杂度 平均 O(n^2) 最好 O(n) 最坏 O(n^2) 空间复杂度 O(1) 稳定
public void bubbleSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
boolean flag = true;
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
flag = false;
}
}
if (flag) break;
}
}
快速排序 时间复杂度 平均 O(nlog(n)) 最好 O(nlog(n)) 最坏 O(n^2) 空间复杂度 O(logn) 不稳定
public void quickSort(int[] arr, int left, int right) {
if (left >= right) return;
int i = left - 1, j = right + 1, mid = arr[(left + right) >> 1], temp;
while (i < j) {
do i++; while (arr[i] < mid);
do j--; while (arr[j] > mid);
if (i < j) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
quickSort(arr, left, j);
quickSort(arr, j + 1, right);
}
归并排序 时间复杂度 平均 O(nlog(n)) 最好 O(nlog(n)) 最坏 O(nlog(n)) 空间复杂度 O(n) 稳定
public void mergeSort(int[] arr, int left, int right, int[] temp) {
if (left < right) {
int mid = (left + right) / 2;
mergeSort(arr, left, mid, temp);
mergeSort(arr, mid + 1, right, temp);
merge(arr, left, mid, right, temp);
}
}
/**
* @param arr 排序的原始数组
* @param left 左边有序序列的初始索引
* @param mid 中间索引
* @param right 右边索引
* @param temp 中转的数组
*/
public void merge(int[] arr, int left, int mid, int right, int[] temp) {
int i = left, j = mid + 1, t = 0, tempLeft; //t是 temp数组的当前索引
//将左右两边的数据按照规则填充到 temp数组中,直到有一边处理完毕为止
while (i <= mid && j <= right) {
temp[t++] = arr[i] <= arr[j] ? arr[i++] : arr[j++];//如果左边序列的元素小于右边 将左边当前元素添加到 temp数组
}
//有剩余数据的一边填充到 temp中
while (i <= mid) {
temp[t++] = arr[i++];
}
while (j <= right) {
temp[t++] = arr[j++];
}
t = 0;
tempLeft = left;
while (tempLeft <= right) {
arr[tempLeft++] = temp[t++];
}
}
基数排序 时间复杂度 平均O(d(r+n)) 最好O(d(n+rd)) 最坏O(d(r+n)) 空间O(rd+n) 稳定 r是关键字的基数,d是长度,n是关键字的个数
public void RadixSort(int[] arr) {
int max = arr[0], maxLen;
for (int i = 0; i < arr.length; i++) {
if (max < arr[i]) max = arr[i];
}
maxLen = (max + "").length();//最大数的长度
int[][] bucket = new int[10][arr.length];
int[] elementCount = new int[10];
for (int i = 0, n = 1; i < maxLen; i++, n *= 10) {
for (int j = 0; j < arr.length; j++) {
int digit = arr[j] / n % 10;
bucket[digit][elementCount[digit]++] = arr[j]; //按照位放入桶中
}
int index = 0;
for (int k = 0; k < elementCount.length; k++) {
if (elementCount[k] != 0) {
for (int l = 0; l < elementCount[k]; l++) {
arr[index++] = bucket[k][l];
}
}
elementCount[k] = 0;
}
}
}
```**插入排序 时间复杂度 平均 O(n^2) 最好 O(n) 最坏 O(n^2) 空间复杂度 O(1) 稳定**
```java
public void insertSort(int[] arr) {
int value, j;
for (int i = 1; i < arr.length; i++) {
value = arr[i];
for (j = i - 1; j >= 0 && value < arr[j]; j--) {
arr[j + 1] = arr[j];
}
arr[j + 1] = value;
}
}
希尔排序 时间复杂度 平均 O(n^1.3~2) 最好 O(n) 最坏 O(n^2) 空间复杂度 O(1) 不稳定
public void shellSort(int[] arr) {
int j, temp;
for (int gap = arr.length / 2; gap > 0; gap /= 2) {
for (int i = gap; i < arr.length; i++) {
j = i;
temp = arr[j];
if (temp < arr[j - gap]) {
while (j - gap >= 0 && temp < arr[j - gap]) {
arr[j] = arr[j - gap];
j -= gap;
}
arr[j] = temp;
}
}
}
}
选择排序 时间复杂度 平均 O(n^2) 最好 O(n^2) 最坏 O(n^2) 空间复杂度 O(1) 不稳定
public void selectSort(int[] arr) {
int min, minIndex;
for (int i = 0; i < arr.length; i++) {
min = arr[i];
minIndex = i;
for (int j = i + 1; j < arr.length; j++) {
if (min > arr[j]) {
min = arr[j];
minIndex = j;
}
}
if (minIndex != i) {
arr[minIndex] = arr[i];
arr[i] = min;
}
}
}
堆排序 时间复杂度 平均 O(nlog(n)) 最好 O(nlog(n)) 最坏 O(nlog(n)) 空间复杂度 O(1) 不稳定
public void heapSort(int[] arr) {
for (int i = arr.length / 2 - 1; i >= 0; i--) {
adjustHeap(arr, i, arr.length);
}
for (int j = arr.length - 1; j > 0; j--) {
int temp = arr[j];
arr[j] = arr[0];
arr[0] = temp;
adjustHeap(arr, 0, j);
}
}
public void adjustHeap(int[] arr, int i, int length) {
int temp = arr[i];
for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {
if (k + 1 < length && arr[k] < arr[k + 1]) {
k++;
}
if (temp < arr[k]) {
arr[i] = arr[k];
i = k;
} else {
break;
}
arr[i] = temp;
}
}
冒泡排序 时间复杂度 平均 O(n^2) 最好 O(n) 最坏 O(n^2) 空间复杂度 O(1) 稳定
public void bubbleSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
boolean flag = true;
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
flag = false;
}
}
if (flag) break;
}
}
快速排序 时间复杂度 平均 O(nlog(n)) 最好 O(nlog(n)) 最坏 O(n^2) 空间复杂度 O(logn) 不稳定
public void quickSort(int[] arr, int left, int right) {
if (left >= right) return;
int i = left - 1, j = right + 1, mid = arr[(left + right) >> 1], temp;
while (i < j) {
do i++; while (arr[i] < mid);
do j--; while (arr[j] > mid);
if (i < j) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
quickSort(arr, left, j);
quickSort(arr, j + 1, right);
}
归并排序 时间复杂度 平均 O(nlog(n)) 最好 O(nlog(n)) 最坏 O(nlog(n)) 空间复杂度 O(n) 稳定
public void mergeSort(int[] arr, int left, int right, int[] temp) {
if (left < right) {
int mid = (left + right) / 2;
mergeSort(arr, left, mid, temp);
mergeSort(arr, mid + 1, right, temp);
merge(arr, left, mid, right, temp);
}
}
/**
* @param arr 排序的原始数组
* @param left 左边有序序列的初始索引
* @param mid 中间索引
* @param right 右边索引
* @param temp 中转的数组
*/
public void merge(int[] arr, int left, int mid, int right, int[] temp) {
int i = left, j = mid + 1, t = 0, tempLeft; //t是 temp数组的当前索引
//将左右两边的数据按照规则填充到 temp数组中,直到有一边处理完毕为止
while (i <= mid && j <= right) {
temp[t++] = arr[i] <= arr[j] ? arr[i++] : arr[j++];//如果左边序列的元素小于右边 将左边当前元素添加到 temp数组
}
//有剩余数据的一边填充到 temp中
while (i <= mid) {
temp[t++] = arr[i++];
}
while (j <= right) {
temp[t++] = arr[j++];
}
t = 0;
tempLeft = left;
while (tempLeft <= right) {
arr[tempLeft++] = temp[t++];
}
}
基数排序 时间复杂度 平均O(d(r+n)) 最好O(d(n+rd)) 最坏O(d(r+n)) 空间O(rd+n) 稳定 r是关键字的基数,d是长度,n是关键字的个数
public void RadixSort(int[] arr) {
int max = arr[0], maxLen;
for (int i = 0; i < arr.length; i++) {
if (max < arr[i]) max = arr[i];
}
maxLen = (max + "").length();//最大数的长度
int[][] bucket = new int[10][arr.length];
int[] elementCount = new int[10];
for (int i = 0, n = 1; i < maxLen; i++, n *= 10) {
for (int j = 0; j < arr.length; j++) {
int digit = arr[j] / n % 10;
bucket[digit][elementCount[digit]++] = arr[j]; //按照位放入桶中
}
int index = 0;
for (int k = 0; k < elementCount.length; k++) {
if (elementCount[k] != 0) {
for (int l = 0; l < elementCount[k]; l++) {
arr[index++] = bucket[k][l];
}
}
elementCount[k] = 0;
}
}
}