Arrays中排序调用DualPivotQuicksort的sort方法。
- DualPivotQuicksort 类注释中说明,该类方法只供程序包内部调用,在arrays中使用。
int[] 数组排序
-
初始判断,如果数组长度<286,使用快速排序(QUICKSORT),
leftmost = true
,默认范围在最左方 -
进入快速排序方法(QUICKSORT),再次判断如果数组长度 <47 ,使用插入排序(INSERTION_SORT),并带入最初入参
leftmost = true
-
插入排序(INSERTION_SORT) 最初入参
leftmost = true
,进入的代码区块如下
for (int i = left, j = i; i < right; j = ++i) {
//i = 第一个数的下标
int ai = a[i + 1];//获取下一个数
while (ai < a[j]) { //下一个数小于当前数
a[j + 1] = a[j];//将当前数后移一位
if (j-- == left) {//至数组最前方
break;
}
}
a[j + 1] = ai;//将空出来的位置赋予ai
}
- 数组长度 >47 时排序方法
// Inexpensive approximation of length / 7
// 快速获取 长度/7 的值 ,位运算 1/7 = 1/8 + 1/64
int seventh = (length >> 3) + (length >> 6) + 1;
/*
* Sort five evenly spaced elements around (and including) the
* center element in the range. These elements will be used for
* pivot selection as described below. The choice for spacing
* these elements was empirically determined to work well on
* a wide variety of inputs.
*/
// e1 e2 e3 e4 e5 间隔 length/7
int e3 = (left + right) >>> 1; // The midpoint
int e2 = e3 - seventh;
int e1 = e2 - seventh;
int e4 = e3 + seventh;
int e5 = e4 + seventh;
// Sort these elements using insertion sort
//将 e1 e2 e3 e4 e5 先排序
if (a[e2] < a[e1]) { int t = a[e2]; a[e2] = a[e1]; a[e1] = t; }
if (a[e3] < a[e2]) { int t = a[e3]; a[e3] = a[e2]; a[e2] = t;
if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; }
}
if (a[e4] < a[e3]) { int t = a[e4]; a[e4] = a[e3]; a[e3] = t;
if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t;
if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; }
}
}
if (a[e5] < a[e4]) { int t = a[e5]; a[e5] = a[e4]; a[e4] = t;
if (t < a[e3]) { a[e4] = a[e3]; a[e3] = t;
if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t;
if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; }
}
}
}
// Pointers 定义大小两个数组下标
int less = left; // The index of the first element of center part
int great = right; // The index before the first element of right part
准备工作结束,开始排序,首先判断选出来的四个节点不相等的情况
//四个指针不相等
if (a[e1] != a[e2] && a[e2] != a[e3] && a[e3] != a[e4] && a[e4] != a[e5]) {
/*
* Use the second and fourth of the five sorted elements as pivots.
* These values are inexpensive approximations of the first and
* second terciles of the array. Note that pivot1 <= pivot2.
*/
// e2 e4的值给两个指针
int pivot1 = a[e2];
int pivot2 = a[e4];
/*
* The first and the last elements to be sorted are moved to the
* locations formerly occupied by the pivots. When partitioning
* is complete, the pivots are swapped back into their final
* positions, and excluded from subsequent sorting.
*/
//将要排序的第一个和最后一个元素移到以前由枢轴占据的位置。 分区时完成后,枢轴将交换回其最终位置位置,并从后续排序中排除。
a[e2] = a[left];
a[e4] = a[right];
/*
* Skip elements, which are less or greater than pivot values.
*/
//less 和 greate 和指针对比,找到前后第一个分割点,源码中官方给的图形象的说明了结果
while (a[++less] < pivot1);
while (a[--great] > pivot2);
/*
* 交换指针的值,之前赋值
* int pivot1 = a[e2];
* int pivot2 = a[e4];
* a[e2] = a[left];
* a[e4] = a[right];
*
* 由于a[++less] < pivot1 为false,pivot1 应至less前一位
* */
// Swap pivots into their final positions
a[left] = a[less - 1]; a[less - 1] = pivot1;
a[right] = a[great + 1]; a[great + 1] = pivot2;
// Sort left and right parts recursively, excluding known pivots
//将两部分数组分组递归排序
sort(a, left, less - 2, leftmost);
sort(a, great + 2, right, false);
/*
* If center part is too large (comprises > 4/7 of the array),
* swap internal pivot values to ends.
*/
//跳过相同数字
if (less < e1 && e5 < great) {
/*
* Skip elements, which are equal to pivot values.
*/
while (a[less] == pivot1) {
++less;
}
while (a[great] == pivot2) {
--great;
}
}
// Sort center part recursively
//递归排序中间部分 学个英语单词recursively(递归的)
sort(a, less, great, false);
}
- 接下来看
leftmost = false
进入的代码区块,最初进入先进行有序判断
do {
if (left >= right) {
return;
}
} while (a[++left] >= a[left - 1]);
//初始判断数组是否已经是有序数组,如果数组每个数右边均大于左边,则数组为有序数组
- 进入排序代码块,官方称此排序方法为配对插入排序(pair insertion sort),
待续。。。。