看书看到排序这一章 回去回味了一下快拍 突然觉得 自己应该总结一下
快排 每次把一个flag放置到其标准的位置上 然后递归:算法如下
private static void quickSort(int[] array,int left,int right){
if(left<right){
int temp =array[left];
int i=left,j;
for(j=left+1;j<=right;j++){
if(array[j]<temp){
int t=array[j];
array[j]=array[i+1];
array[i+1]=t;
i++;
}
}
array[left]=array[i];
array[i]=temp;
quickSort(array,left,i-1);
quickSort(array,i+1,right);
}
}
ARRAYS.sort 表明使用了快排其实不然 主要是用的递归的思想:并分开考虑(原因就是对对象需要稳定的排序 而 快排不是标准的类型)
基本类型:采用调优的快速排序;
对象类型:采用改进的归并排序。
排序优化:实现中快排和归并都采用递归方式,而在递归的底层,也就是待排序的数组长度小于7时,直接使用冒泡排序,而不再递归下去。
主要做了一下几个方面:
1)当待排序的数组中的元素个数较少时,源码中的阀值为7,采用的是插入排序。尽管插入排序的时间复杂度为0(n^2),但是当数组元素较少时,插入排序优于快速排序,因为这时快速排序的递归操作影响性能。
2)较好的选择了划分元(基准元素)。能够将数组分成大致两个相等的部分,避免出现最坏的情况。例如当数组有序的的情况下,选择第一个元素作为划分元,将使得算法的时间复杂度达到O(n^2).
源码中选择划分元的方法:
当数组大小为 size=7 时 ,取数组中间元素作为划分元。int n=m>>1;(此方法值得借鉴)
当数组大小 7<size<=40时,取首、中、末三个元素中间大小的元素作为划分元。
当数组大小 size>40 时 ,从待排数组中较均匀的选择9个元素,选出一个伪中数做为划分元。
举例:
15、93、15、41、6、15、22、7、15、20
因 7<size<=40,所以在15、6、和20 中选择v = 15 作为划分元。
经过一次换分后: 15、15、7、6、41、20、22、93、15、15. 与划分元相等的元素都移到了素组的两边。
接下来将与划分元相等的元素移到数组中间来,形成:7、6、15、15、15、15、41、20、22、93.
最后递归对两个区间进行排序[7、6]和[41、20、22、93].
小宇7直接使用插排
在1.7中修改了快排 dualprvotquicksort
流程如下~~思想差不多 就不啰嗦了(想啰嗦也不会啊 混蛋)
ARRAYS.parallelSort
java 1.7 以后推出了fork-join框架~~~ 原因么 就是现在都是多核处理器了 fork join 是贴合多核处理 提高效率的
在1.8中退出了parallelSort 字面理解是 并行排序实际实现呢~~我们看看源码好咯:
public static void parallelSort(int[] a) {
int n = a.length, p, g;
if (n <= MIN_ARRAY_SORT_GRAN ||
(p = ForkJoinPool.getCommonPoolParallelism()) == 1)
DualPivotQuicksort.sort(a, 0, n - 1, null, 0, 0);
else
new ArraysParallelSortHelpers.FJInt.Sorter
(null, a, new int[n], 0, n, 0,
((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
MIN_ARRAY_SORT_GRAN : g).invoke();
}
MIN_ARRAY_SORT_GRAN 为8192啊
嘿嘿 ,可以看到 系统是没8192个数 启动fork一个进程 进行dualpivotquicksort排序(目前就理解这么浅啊 ,看了半天看下去浑蛋)