int[]排序
- 长度大于QUICKSORT_THRESHOLD(286)时,调用sort方法
- 长度大于INSERTION_SORT_THRESHOLD时,采用快排
- 优化:对Pivot的选取。通过位运算,获取长度1/7近似值。以长度中点、中点左右1/7、2/7共5个值作为Pivot
- 小于的,使用插入排序
- 否则,判断是否高度结构化(即,是否已经接近排序完成
- 定义一个常量MAX_RUN_COUNT = 67;
- 定义一个计数器int count = 0; 定义一个数组int[] run 使之长度为MAX_RUN_COUNT + 1;
- 令run[0] = left, 然后从传入数组的最左侧left开始遍历,
- 若数组的前n个元素均为升序/降序排列, 而第n + 1个元素的升/降序发生了改变, 则++count,并将第n个元素的索引存入run[conut]
- 若数组中连续相等的元素长度超过MAX_RUN_LENGTH(33),就调用快排
- 在遍历过程中,将降序的序列进行翻转变为升序
- 如果conut<MAX_RUN_COUNT,即升序降序改变次数小于67次,就认为是高度结构化的
- 高度结构化的,如果还未排好序,使用归并排序
- 未高度结构化的,使用快排

快排

//选取Pivot:通过位运算获取数组长度的1/7的近似值(位运算无法精确表示1/7)int seventh = (length >> 3) + (length >> 6) + 1;//获取数组中间位置左右1/7、2/7处的索引(e1、e2、e4、e5)int e3 = (left + right) >>> 1; int e2 = e3 - seventh;int e1 = e2 - seventh;int e4 = e3 + seventh;int e5 = e4 + seventh;//对e1-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; } } } }int less = left; int great = right; //5个元素没有相同的,就以e2、e4作为双枢轴if (a[e1] != a[e2] && a[e2] != a[e3] && a[e3] != a[e4] && a[e4] != a[e5]) { int pivot1 = a[e2]; int pivot2 = a[e4]; a[e2] = a[left]; a[e4] = a[right]; //使得less左边元素都小于pivot1,great元素右边都小于povot2 while (a[++less] < pivot1); while (a[--great] > pivot2); //开始排序,对less和great之间的元素排序,达到下图的效果 /* * Partitioning: * * left part center part right part * +--------------------------------------------------------------+ * | < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 | * +--------------------------------------------------------------+ * ^ ^ ^ * | | | * less k great * * Invariants: * * all in (left, less) < pivot1 * pivot1 <= all in [less, k) <= pivot2 * all in (great, right) > pivot2 * * Pointer k is the first index of ?-part. */ outer: for (int k = less - 1; ++k <= great; ) { int ak = a[k]; if (ak < pivot1) { //ak跟a[less]交换 a[k] = a[less]; a[less] = ak; ++less; } else if (ak > pivot2) { //如果great大于pivot2,great继续往左边移动 while (a[great] > pivot2) { if (great-- == k) { break outer; } } if (a[great] < pivot1) { //great小于pivot1,将great移到less的位置 a[k] = a[less]; a[less] = a[great]; ++less; } else { // pivot1 <= a[great] <= pivot2,将great赋值到k的位置 a[k] = a[great]; } //ak跟a[great]交换 a[great] = ak; --great; } } // 定位pivot1和pivot2的位置 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; } /* * Partitioning: * * left part center part right part * +----------------------------------------------------------+ * | == pivot1 | pivot1 < && < pivot2 | ? | == pivot2 | * +----------------------------------------------------------+ * ^ ^ ^ * | | | * less k great * * Invariants: * * all in (*, less) == pivot1 * pivot1 < all in [less, k) < pivot2 * all in (great, *) == pivot2 * * Pointer k is the first index of ?-part. */ outer: for (int k = less - 1; ++k <= great; ) { int ak = a[k]; if (ak == pivot1) { // Move a[k] to left part a[k] = a[less]; a[less] = ak; ++less; } else if (ak == pivot2) { // Move a[k] to right part while (a[great] == pivot2) { if (great-- == k) { break outer; } } if (a[great] == pivot1) { // a[great] < pivot2 a[k] = a[less]; /* * Even though a[great] equals to pivot1, the * assignment a[less] = pivot1 may be incorrect, * if a[great] and pivot1 are floating-point zeros * of different signs. Therefore in float and * double sorting methods we have to use more * accurate assignment a[less] = a[great]. */ a[less] = pivot1; ++less; } else { // pivot1 < a[great] < pivot2 a[k] = a[great]; } a[great] = ak; --great; } } } // Sort center part recursively sort(a, less, great, false); } else { // Partitioning with one pivot //存在相同元素,就使用e3作为枢轴 int pivot = a[e3]; /* * Partitioning degenerates to the traditional 3-way * (or "Dutch National Flag") schema: * * left part center part right part * +-------------------------------------------------+ * | < pivot | == pivot | ? | > pivot | * +-------------------------------------------------+ * ^ ^ ^ * | | | * less k great * * Invariants: * * all in (left, less) < pivot * all in [less, k) == pivot * all in (great, right) > pivot * * Pointer k is the first index of ?-part. */ for (int k = less; k <= great; ++k) { if (a[k] == pivot) { continue; } int ak = a[k]; //小于pivot,直接将k与less交换 if (ak < pivot) { a[k] = a[less]; a[less] = ak; ++less; } else { //开始反向从great遍历,如果great元素>枢轴,无需交换,great向前移动 while (a[great] > pivot) { --great; } //great元素小于pviot,就跟先将less复制到k指向的位置(此时k位置原本的元素由ak保存),然后将great元素复制到less,less++ //即,less-->k, great-->less交换,k -->great if (a[great] < pivot) { // a[great] <= pivot a[k] = a[less]; a[less] = a[great]; ++less; } else { //如果great等于pivot,将pivot的值直接复制到k指向的位置 a[k] = pivot; } //将k的元素复制到great a[great] = ak; --great; } } /* * Sort left and right parts recursively. * All elements from center part are equal * and, therefore, already sorted. */ sort(a, left, less - 1, leftmost); sort(a, great + 1, right, false); }
高度结构化判断
// Check if the array is nearly sorted // k的值表示多个升序序列尾部索引,count表示升降序改变次数 for (int k = left; k < right; run[count] = k) { if (a[k] < a[k + 1]) { //升序 while (++k <= right && a[k - 1] <= a[k]); } else if (a[k] > a[k + 1]) { //降序 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 { //相同元素超过33,使用快排 for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) { if (--m == 0) { sort(a, left, right, true); return; } } } //当遍历过程中发现变化次数高于33次时,直接使用快排 if (++count == MAX_RUN_COUNT) { sort(a, left, right, true); return; } }
T[]排序
参见容器排序:https://www.yuque.com/zhicizhongnian/nr4160/huyv1h