排序算法不管是在面试中,还是在平时的开发中,都经常用到,本文对十种排序算法进行总结,比较它们的优劣!!!
十大排序算法
1. 时间、空间复杂度对比
中文名称 | 英文名称 | 平均时间复杂度 | 最坏时间复杂度 | 最好时间复杂度 | 空间复杂度 | 稳定性 |
---|---|---|---|---|---|---|
选择排序 | Selection | n2 | n2 | n2 | 1 | 不稳 |
冒泡排序 | Bubble | n2 | n2 | n | 1 | 稳 |
插入排序 | Insertion | n2 | n2 | n | 1 | 稳 |
堆排序 | Heap | nlog2n | nlog2n | nlog2n | 1 | 不稳 |
希尔排序 | Shell | n1.3 | n2 | n | 1 | 不稳 |
归并排序 | Merge | nlog2n | nlog2n | nlog2n | n | 稳 |
快速排序 | Quick | nlog2n | n2 | nlog2n | log2n | 不稳 |
桶排序 | Bucket | n+k | n2 | n | n+k | 稳 |
计数排序 | Counting | n+k | n+k | n+k | n+k | 稳 |
基数排序 | Radix | n*k | n*k | n*k | n+k | 稳 |
2.十大排序总结
2.1 选择排序
选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n - 1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。
选择排序有两步,代码实现步骤比较简单。
- 比较,找出这一趟最小值处的索引index
- 交换swap
/**
* 选择排序
*/
public class SelectionSort {
public static void main(String[] args) {
int[] arr = {
5, 3, 1, 4, 2};//对该数组排序
//从数组的第一个元素开始,从前往后,总共需要比较N-1趟
for (int i = 0; i < arr.length-1; i++) {
//记录每一趟最小值处的索引
int minPos = i;
//这层循环进行比较、交换
for(int j=i+1; j<arr.length; j++) {
//比较、更新最小值索引
minPos = arr[j] < arr[minPos] ? j : minPos;
}
//交换
swap(arr,i,minPos);
}
}
static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
2.2 冒泡排序
冒泡排序就是利用循环,将当前最大的元素移到靠后的位置
下面数组arr = {9, 3, 1, 4, 6, 8, 7, 5, 2},通过比较将最大的元素9移到最后
arr1 = {3, 1, 4, 6, 8, 7, 5, 2, 9};
依次类推,加一层外循环,得到排序好的数组
/**
* 冒泡排序
*/
public class BubbleSort {
public static void main(String[] args) {
int[] arr = {
9, 3, 1, 4, 6, 8, 7, 5, 2};
//第一层循环表示趟数,有arr.length个数,那么仅需要arr.length-1趟
//仅剩两个数的时候,只需要1趟即可
for (int i = 0; i < arr.length-1; i++) {
//比较当前元素与下一个元素的大小
//若当前元素大于下一个元素,执行交换方法
for (int j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j+1]) swap(arr, j, j+1);
}
}
}
static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
2.3 插入排序
插排的核心思想就是原始数组分成两个子数组,左数组Left是有序的,右数组Right是无序的。
初始:把数组的第一个元素当成Left,其余元素当成Right,Right数组的第一个元素开始向Left当中插入。插入的原则是,将该元素插入到第一个比该元素大的位置的左侧!!!
如何找到合适的位置,循环比较(类似冒泡排序的思想),一直比较、交换找到合适的位置。
/**
* 插入排序
*/
public class InsertionSort {
public static void main(String[] args) {
int[] arr = {
6, 2, 5, 4, 8};
//从Right的第一个元素开始{2, 5, 4, 8}
for (int i = 1; i < arr.length; i++) {
//从Left数组的最后一个元素开始,往前进行比较
//j--表示Left数组从后往前
for (int j = i; j > 0; j--) {
//若插入元素小于Left数组的arr[j-1],则交换