携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第15天,点击查看活动详情
指定数组升序排序
Arrays.java类
public static void sort(int[] a) {
DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
}
如果元素小于286,使用快速排序
但对于该方法中还进行有单独判断用来区分相应排序规则(插入排序或者快速排序)
DualPivotQuicksort.sort(int[] a, int left, int right,
int[] work, int workBase, int workLen){
// 小型数组上使用快速排序---QUICKSORT_THRESHOLD=286为阀值
if (right - left < QUICKSORT_THRESHOLD) {
// 对<286的数组集合单独区分排序
sort(a, left, right, true);
return;
}
... ...
}
如果元素小于47的时候使用插入排序
sort(int[] a, int left, int right, boolean leftmost) {
int length = right - left + 1;
// 在小型数组上使用插入排序---INSERTION_SORT_THRESHOLD=47为阀值
if (length < INSERTION_SORT_THRESHOLD) {
... ...
}
}
如果元素大于47的使用快速排序
- 从数列中挑出5个元素作为基准
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作
- 递归(recursive)地把小于基准值元素的子数列和大于基准值元素的子数列排序
如果元素大于286,使用归并排序
- 排序前会判断排序的数据是否具备结构,不具备高度结构化的使用快速排序
// Check if the array is nearly sorted
for (int k = left; k < right; run[count] = k) {
if (a[k] < a[k + 1]) { // ascending
while (++k <= right && a[k - 1] <= a[k]);
} else if (a[k] > a[k + 1]) { // descending
while (++k <= right && a[k - 1] >= a[k]);
for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
int t = a[lo]; a[lo] = a[hi]; a[hi] = t;
}
} else { // equal
for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {
if (--m == 0) {
sort(a, left, right, true);
return;
}
}
}
/*
* The array is not highly structured,
* use Quicksort instead of merge sort.
*/
if (++count == MAX_RUN_COUNT) {
sort(a, left, right, true);
return;
}
}
总的排序流程
包含有插入排序,快速排序,归并排序三种排序的组合
- 0~47:插入排序
- 47~286:快速排序
- 大于286:
- 具备高度结构化数据:归并排序
- 不具备:>47:快速排序