常见的排序时间复杂度与空间复杂度
排序算法 |
平均时间复杂度 |
最坏时间复杂度 |
空间复杂度 |
是否稳定 |
冒泡排序 |
O(n2) |
O(n2) |
O(1) |
是 |
选择排序 |
O(n2) |
O(n2) |
O(1) |
不是 |
直接插入排序 |
O(n2) |
O(n2) |
O(1) |
是 |
归并排序 |
O(nlogn) |
O(nlogn) |
单元格 |
是 |
快速排序 |
O(nlogn) |
O(n2) |
O(nlogn) |
不是 |
堆排序 |
O(nlogn) |
O(nlogn) |
O(1) |
不是 |
希尔排序 |
O(nlogn) |
O(ns) |
O(1) |
不是 |
计数排序 |
O(n+k) |
O(n+k) |
O(n+k) |
是 |
基数排序 |
O(N∗M) |
O(N∗M) |
O(M) |
是 |
排序原理动画
实现代码
快速排序
package com.leetcode.sort;
import java.util.Arrays;
/**
* @Auther: Jibny Zhan
* @Date: 2019/11/30 20:12
* @Description:
*/
public class QuickSort {
private static int count;
private static void QuickSort(int[] num, int left, int right) {
if (left >= right)
return;
int i = left;
int j = right;
int key = num[left];
while (i < j) {
if (num[j] >= key && i < j)
j--;
else if (num[i] <= key && i < j)
i++;
else {
num[i] ^= num[j];
num[j] ^= num[i];
num[i] ^= num[j];
}
}
num[left] = num[i];
num[i] = key;
count++;
QuickSort(num, left, i - 1);
QuickSort(num, i + 1, right);
}
public static void main(String[] args) {
int[] num = {45, 3, 78, 64, 52, 11, 64, 55, 99, 11, 18};
System.out.println(Arrays.toString(num));
QuickSort(num, 0, num.length - 1);
System.out.println(Arrays.toString(num));
System.out.println("数组个数:" + num.length);
System.out.println("循环次数:" + count);
}
}
归并排序
package com.leetcode.sort;
import java.util.Arrays;
/**
* @Auther: Jibny Zhan
* @Date: 2019/12/1 00:42
* @Description:
*/
public class MergeSort {
private static void sort(int[] arr) {
mergeSort(arr, 0, arr.length - 1);
}
//分割
private static void mergeSort(int[] arr, int left, int right) {
if (left == right)
return;
int mid = (left + right) >> 1;
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
merge(arr, left, mid, right);
}
//合并
private static void merge(int[] arr, int left, int mid, int right) {
int[] temp = new int[right - left + 1];
int i = 0;
int p1 = left;
int p2 = mid + 1;
while (p1 <= mid && p2 <= right)
temp[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
while (p1 <= mid)
temp[i++] = arr[p1++];
while (p2 <= right)
temp[i++] = arr[p2++];
for (i = 0; i < temp.length; i++) {
arr[left + i] = temp[i];
}
}
public static void main(String[] args) {
int[] nums = {2, 5, 3, 1, 10, 4, 6, 9};
sort(nums);
System.out.println(Arrays.toString(nums));
}
}
堆排序
package com.leetcode.sort;
import java.util.Arrays;
/**
* @Auther: Jibny Zhan
* @Date: 2019/11/30 20:36
* @Description:
*/
public class HeapSort {
private static int count;
// 1.调整堆
public static void heapify(int[] tree, int n, int i) {
if (i >= n)
return;
count++;
int right = (i << 1) + 1;
int left = (i << 1) + 2;
int max = i;
if (left < n && tree[left] > tree[max]) {
max = left;
}
if (right < n && tree[right] > tree[max]) {
max = right;
}
if (max != i) {
swap(tree, i, max);
heapify(tree, n, max);
}
}
// 2.构建堆,从后往前调整堆
public static void buildHeap(int[] tree, int n) {
int lastNode = n - 1;
int parent = (lastNode - 1) >> 1;
int i = parent;
for (i = parent; i >= 0; i--) {
heapify(tree, n, i);
}
}
// 3.交换堆顶和末尾元素
public static void heapSort(int[] tree, int n) {
buildHeap(tree, n);
int i;
for (i = n - 1; i >= 0; i--) {
swap(tree, i, 0);
heapify(tree, i, 0);
}
}
public static void swap(int[] tree, int A, int B) {
tree[A] ^= tree[B];
tree[B] ^= tree[A];
tree[A] ^= tree[B];
}
public static void main(String[] args) {
int[] tree = {2, 5, 3, 1, 10, 4};
heapSort(tree, tree.length);
System.out.println(Arrays.toString(tree));
System.out.println("循环次数:" + count);
}
}
桶排序
package com.leetcode.sort;
import java.util.Arrays;
/**
* @Auther: Jibny Zhan
* @Date: 2019/11/30 21:47
* @Description:
*/
public class BucketSort {
public static int[] bucketSort(int[] nums, int maxNum){
int[] sorted = new int[maxNum+1];
for(int i=0; i<nums.length; i++){
sorted[nums[i]] = nums[i];//把数据放到对应索引的位置
}
return sorted;
}
public static void main(String[] args) {
int[] x = { 99, 65, 24, 47, 50, 88,33, 66, 67, 31, 18 };
int[] sorted = bucketSort(x, 99);
System.out.println(Arrays.toString(sorted));
}
}