排序问题是算法里面的经典问题,也是计算机学科数据结构课程里面的必修课,面对诸多的如插入排序,快速排序,堆排序,归并排序等等经典排序算法,
sort()是Java中用来排序的一个方法,在我们专心学习各种经典排序算法的时候,其实在代码中一个sort()就可以解决。
我们经常使用的对数据进行排序的算法Arrays.sort,Collections.sort方法,那么JDK的实现者是如何选择排序算法的呢?这是一个常见的面试问题。
事实上Collections.sort方法底层就是调用的Arrays.sort方法,所以我们只分析Arrays.sort就好。
Arrays.sort(int[])方法来概述基本类型排序的基本思路如下:
- 如果数组元素个数小于47个,那么使用改进的插入排序进行排序
- 如果元素个数大于47个并且小于快速排序的阈值286个,则使用双轴快速排序进行排序
- 如果元素个数大于286个,根据数组的无序程度来判定继续使用哪种算法,无序程度通过将数组划分为不同的有序序列的个数来判定。
- 如果有序序列的个数大于67个,则认为原数组基本无序,则仍然使用双轴快速排序,如果小于67个,则认为原数组基本有序,使用归并排序进行排序。
也就是说,划分出有序序列个数越多,其实原数组是越无序的。这里理解不了的同学,可以往极限想一下。一个完全有序的数组,只能划分出1个有序数组。而一个完全逆序的数组,数组size有多大,就能划分出多少个有序数组。
若果是Arrays.sort(Object object),会涉及稳定性的问题。因为快排是是不稳定的,所以当数组个数超过插入排序的阈值后,不会使用快排,而是使用归并排序。
这里的稳定是指比较相等的数据在排序之后仍然按照排序之前的前后顺序排列。