快速排序
概述
快速排序,听名字就是使用这玩意排序很快,但其实在最差的情况下他的时间复杂度是O(n2),和冒泡排序一样,平均时间复杂度为O(nlogn),还不错,听说使用的场景很多,但是我看了java8中ArrayList中的sort方法,使用的并不是这个算法,其他的在什么地方有使用,不太清楚。
核心思想
这个排序算法的核心思想就是分而治之,把一个大的数组分成一小块一小块,然后在每一块上排序。这样叙述干巴巴的,可以参考这篇文章:https://wiki.jikexueyuan.com/project/easy-learn-algorithm/fast-sort.html,个人认为,看这篇就够了,不用看我的,我写的只是为了记录一下,把自己的思路整理一下,方便以后自己查看,但是如果你有兴趣看看,也可以吧,我也没啥意见O(∩_∩)O哈哈~
举例如下:
3, 5, 2, 4, 1
要求:使用快速排序算法进行排序
快速排序实现如下:
第一步:先找出基准数(就是在需要排序的数据中随便找一个数),一般常见的就是把第一个数作为基准数,所以基准数 = 3
第二步:搞两个哨兵,第一个哨兵从左往右找,第二个哨兵从右往左找,具体如下
- 第二个哨兵先开始(这个非常重要,至于原因大家实现一遍代码就知道了),发现2<3,好,第二个哨兵暂停
- 第一个哨兵,发现5>3,交换第一个哨兵和第二个哨兵对应的元素,就是交换5和2的位置(至于为什么这么做,一会解释),结果为:3,1,2,4,5
- 再从第二个哨兵开始,发现4>3,继续向左,发现1<3,暂停
- 第一个哨兵向右,这是第一个哨兵和第二个哨兵指向同一个元素,就是1,ok
- 交换基准数3和1的位置,结果为:2,1,3,4,5
总结:到这里,不知道大家发现了什么没有,那我就直接揭晓答案吧,上面在介绍核心思想的时候提到,说快速排序就是分而治之,这里大家可以发现已经把大于3的数和小于3的数放到了一起,然后在大于3的数中,就是4,5中,继续重复第一步和第二步,在小于3的数中,就是2,1,重复第一步和第二步,就可以了。
在第二步中,大家可以发现右边的哨兵想要找到的数是小于基准数的,左边的哨兵想要找到大于基准数的,这样做的目的就是把大于和小于基准数的数分开。
代码实现
本文是java实现,如果你会python或者C,也可以酬和着看,差不太多
/** * @author: steve * @date: 2020/7/6 9:54 * @description: 快速排序实现 */ public class QuickSort { public static int array[] = {72,6,57,88,60,42,83,73,48,8}; // public static int array1[] = {6,1,2,7,9,3,4,5,10,8}; public static void quickSort(int i, int j){ //i > j为非正常状况,直接返回 if (i > j){ return; } int baseNumber = array[i]; int end = j; int start = i; while (j!=i){ //第一个哨兵 while (j > i && array[j] >= baseNumber){ j--; }
//第二个哨兵 while (j > i && array[i] <= baseNumber){ i++; } if (j > i){ swap(i,j); } } //当i = j或者i > j的时候交换基准数和i的位置 swap(start,i);
//处理小于基准数的部分 quickSort(start, i-1); //处理大于基准数的部分 quickSort(i + 1,end); } public static void swap(int i, int j){ int temp = 0; temp = array[i]; array[i] = array[j]; array[j] = temp; } public static void main(String[] args) { quickSort(0,array.length-1); for (int i = 0; i < array.length; i++) { System.out.println(array[i]); } } }
总结:快速排序,上面只是一种普遍的写法,还可以做一些优化,比如选择基准数的地方,有些别的方式,这里就不介绍了。