深入理解java中Arrays.sort()的用法
Java的Arrays类中有一个sort()方法,该方法是Arrays类的静态方法,在需要对数组进行排序时,非常的好用。
但是sort()的参数有好几种,基本上是大同小异,下面是以int型数组为例的Arrays.sort()的典型用法
importjava.util.Arrays;
importjava.util.Comparator;
/**
*Arrays.sort()排序
*/
publicclassSortTest
{
publicstaticvoidmain(String[]args)
{
int[]ints=newint[]{2,324,4,57,1};
System.out.println("增序排序后顺序");
Arrays.sort(ints);
for(inti=0;i()
{
/*
*此处与c++的比较函数构成不一致
*c++返回bool型,而Java返回的为int型
*当返回值>0时
*进行交换,即排序(源码实现为两枢轴快速排序)
*/
publicintcompare(Integero1,Integero2)
{
returno2-o1;
}
publicbooleanequals(Objectobj)
{
returnfalse;
}
});
for(Integerinteger:integers)
{
System.out.print(integer+"");
}
System.out.println("\n对部分排序后顺序");
int[]ints2=newint[]{212,43,2,324,4,4,57,1};
//对数组的[2,6)位进行排序
Arrays.sort(ints2,2,6);
for(inti=0;i
排序结果如下
增序排序后顺序
12457324
减序排序后顺序
32464421
对部分排序后顺序
21243244324571
打开Arrays.sort()源码,还是以int型为例,其他类型也是大同小异
publicstaticvoidsort(int[]a){
DualPivotQuicksort.sort(a,0,a.length-1,null,0,0);
}
publicstaticvoidsort(int[]a,intfromIndex,inttoIndex){
rangeCheck(a.length,fromIndex,toIndex);
DualPivotQuicksort.sort(a,fromIndex,toIndex-1,null,0,0);
}
从源码中发现,两种参数类型的sort方法都调用了DualPivotQuicksort.sort()方法
继续跟踪源码
staticvoidsort(int[]a,intleft,intright,
int[]work,intworkBase,intworkLen){
//UseQuicksortonsmallarrays
if(right-lefta[k+1]){//descending
while(++k<=right&&a[k-1]>=a[k]);
for(intlo=run[count]-1,hi=k;++lo<--hi;){
intt=a[lo];a[lo]=a[hi];a[hi]=t;
}
}else{//equal
for(intm=MAX_RUN_LENGTH;++k<=right&&a[k-1]==a[k];){
if(--m==0){
sort(a,left,right,true);
return;
}
}
}
/*
*Thearrayisnothighlystructured,
*useQuicksortinsteadofmergesort.
*/
if(++count==MAX_RUN_COUNT){
sort(a,left,right,true);
return;
}
}
//Checkspecialcases
//Implementationnote:variable"right"isincreasedby1.
if(run[count]==right++){//Thelastruncontainsoneelement
run[++count]=right;
}elseif(count==1){//Thearrayisalreadysorted
return;
}
//Determinealternationbaseformerge
byteodd=0;
for(intn=1;(n<<=1)work.length){
work=newint[blen];
workBase=0;
}
if(odd==0){
System.arraycopy(a,left,work,workBase,blen);
b=a;
bo=0;
a=work;
ao=workBase-left;
}else{
b=work;
ao=0;
bo=workBase-left;
}
//Merging
for(intlast;count>1;count=last){
for(intk=(last=0)+2;k<=count;k+=2){
inthi=run[k],mi=run[k-1];
for(inti=run[k-2],p=i,q=mi;i=hi||p=lo;
b[i+bo]=a[i+ao]
);
run[++last]=right;
}
int[]t=a;a=b;b=t;
into=ao;ao=bo;bo=o;
}
}
结合文档以及源代码,我们发现,jdk中的Arrays.sort()的实现是通过所谓的双轴快排的算法
/**
*ThisclassimplementstheDual-PivotQuicksortalgorithmby
*VladimirYaroslavskiy,JonBentley,andJoshBloch.Thealgorithm
*offersO(nlog(n))performanceonmanydatasetsthatcauseother
*quicksortstodegradetoquadraticperformance,andistypically
*fasterthantraditional(one-pivot)Quicksortimplementations.
*
*Allexposedmethodsarepackage-private,designedtobeinvoked
*frompublicmethods(inclassArrays)afterperformingany
*necessaryarrayboundschecksandexpandingparametersintothe
*requiredforms.
*
*@authorVladimirYaroslavskiy
*@authorJonBentley
*@authorJoshBloch
*
*@version2011.02.11m765.827.12i:5\7pm
*@since1.7
*/
Java1.8的快排是一种双轴快排,顾名思义:双轴快排是基于两个轴来进行比较,跟普通的选择一个点来作为轴点的快排是有很大的区别的,双轴排序利用了区间相邻的特性,对原本的快排进行了效率上的提高,很大程度上是利用了数学的一些特性。。。。。嗯。。。反正很高深的样子
算法步骤
1.对于很小的数组(长度小于27),会使用插入排序。
2.选择两个点P1,P2作为轴心,比如我们可以使用第一个元素和最后一个元素。
3.P1必须比P2要小,否则将这两个元素交换,现在将整个数组分为四部分:
(1)第一部分:比P1小的元素。
(2)第二部分:比P1大但是比P2小的元素。
(3)第三部分:比P2大的元素。
(4)第四部分:尚未比较的部分。
在开始比较前,除了轴点,其余元素几乎都在第四部分,直到比较完之后第四部分没有元素。
4.从第四部分选出一个元素a[K],与两个轴心比较,然后放到第一二三部分中的一个。
5.移动L,K,G指向。
6.重复45步,直到第四部分没有元素。
7.将P1与第一部分的最后一个元素交换。将P2与第三部分的第一个元素交换。
8.递归的将第一二三部分排序。
疑问:为啥不用泛型
到此这篇关于深入理解java中Arrays.sort()的用法的文章就介绍到这了,更多相关javaArrays.sort()内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!