快速排序、基数排序、选择排序、希尔排序
快速排序
平均时间复杂度O(nlogn) 空间复杂度O(logn)~O(n) 最好情况O(nlogn) 最坏情况O(n²) 不稳定
图解
流程:
- 把数组中最左边的数当做基准,然后从两边进行检索。
- 先从右边往左边检索,检索到比基准小的,停下。
- 从左边往右边检索,检索到比基准大的,停下。
- 交换两个数,然后继续上面两步的检索。
- 当
i=j
相遇的时候,将基准所在元素和相遇位置元素进行交换。(确定下了基准数的最终位置,而且这个数左边的都比它小,右边的都比它大) - 进入基准的左区间,重复上面的流程。
- 进入基准的右区间,重复上面的流程。
1 | public static void quickSort(int[] arr,int left,int right){ |
基数排序
平均时间复杂度O(nk) 空间复杂度O(n+k) 最好情况O(nk) 最坏情况O(n*k) 稳定
流程:
- 找出数组中最大的数,确定这个最大数的位数
n
,进行n
轮排序,每一轮是第i
轮。(i=0,按个位排;i=1,按十位排…) - 创建
10
个桶(二维数组),编号为0-9
,分别对应位数中的0-9
。 - (如果是第一轮)将数组中的元素按照个位上的大小放入对应的桶(数组)中。
- 从
0-9
个桶(数组)中一次按照加入的先后顺序取出,放回原数组中。(这一轮便结束) - (进行第二轮)将数组中的元素按照十位上的大小放入对应的桶(数组)中。
- 同上流程,直到进行完
n
轮排序之后,原数组就是有序的数组了。
1 | public static void radixSort(int[] arr){ |
选择排序
平均时间复杂度O(n²) 空间复杂度O(1) 最好情况O(n²) 最坏情况O(n²) 不稳定
流程:
- 进行
n-1
轮排序。 - 每一轮排序,又是一个循环遍历。
- 假设当前数是最小数。
- 用最小数和后面的每个数进行比较,如果发现有比最小数更小的数,则重新确定最小数,并记录下最小数的下标。
- 遍历到最后时,就得到本轮的最小数和下标。
- 交换当前数和最小数
1 | public static void selectSort(int[] arr){ |
希尔排序
平均时间复杂度O(n1.3) 空间复杂度O(1) 最好情况O(n) 最坏情况O(n²) 不稳定
流程:
- 设置步长,一般设置为
length/2
,然后每一轮步长/2
。 - 每一轮按步长进行分组。
- 每组内使用插入排序。
- 当步长缩小到
1
时,便进行最后一次排序,结束后数组就有序了。
1 | public static void shellSort(int[] arr){ |