前言
本文为本人准备面试前的学习文章,大致上是对Java一些重要知识点的总结归纳,如果有什么错误,请在评论区指出,大家一起进步!!!!
手撕快排代码
public static void quicksort(int[] a,int l,int r){
if(l>=r)return;
int i=l-1;
int j=r+1;
int mid=a[(l+r)>>1];
while(i<j){
do i++;while(a[i]<mid);
do j--;while(a[j]>mid);
if(i<j){
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
quicksort(a,l,j);
quicksort(a,j+1,r);
}
Collections.sort方法底层
整个方法就是它是将所有元素转入一个数组,对数组进行排序,然后,将排好序的序列复制回列表,其中如何排序的方法是调用Arrays.sort方法。
Arrays.sort方法底层
不论是Collections.sort方法或者是Arrays.sort方法,底层实现都是TimSort实现的。TimSort算法就是找到已经排好序数据的子序列,然后对剩余部分排序,然后合并起来。
事实上Collections.sort方法底层就是调用的Arrays.sort方法,而Arrays.sort使用了两种排序方法,快速排序和优化的归并排序。
快速排序(quick)主要是对那些基本类型数据(int, short, long等)排序, 而归并排序(merge)用于对Object类型进行排序。
使用不同类型的排序算法主要是由于快速排序是不稳定的,而归并排序是稳定的。这里的稳定是指比较相等的数据在排序之后仍然按照排序之前的前后顺序排列。对于基本数据类型,稳定性没有意义,而对于Object类型,稳定性是比较重要的,因为对象相等的判断可能只是判断关键属性,最好保持相等对象的非关键属性的顺序与排序前一致;另外一个原因是由于归并排序相对而言比较次数比快速排序少,移动(对象引用的移动)次数比快速排序多,而对于对象来说,比较一般比移动耗时。
此外,对大数组排序。快速排序的sort()采用递归实现,数组规模太大时会发生堆栈溢出,而归并排序sort()采用非递归实现,不存在此问题。
sort()是根据需要排序的数组的长度进行区分的:
首先先判断需要排序的数据量是否大于60。
小于60:使用插入排序,插入排序是稳定的
大于60的数据量会根据数据类型选择排序方式:
基本类型:使用快速排序。「因为基本类型不需要考虑稳定性」
Object类型:使用归并排序「因为归并排序具有稳定性」
注意:不管是快速排序还是归并排序。在二分的时候小于60的数据量依旧会使用插入排序
参考