public static void sort(int[] a) {
DualPivotQuicksort.sort(a,0, a.length - 1, null, 0, 0);
}//DualPivotQuicksort.sort方法
static void sort(int[] a, int left, intright,int[] work, int workBase, intworkLen) {//Use Quicksort on small arrays
if (right - left
sort(a, left, right,true);return;
}/** Index run[i] is the start of i-th run
* (ascending or descending sequence).*/
int[] run = new int[MAX_RUN_COUNT + 1];int count = 0; run[0] =left;//Check if the array is nearly sorted
for (int k = left; k < right; run[count] =k) {//Equal items in the beginning of the sequence
while (k < right && a[k] == a[k + 1])
k++;if (k == right) break; //Sequence finishes with equal items
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]);//Transform into an ascending sequence
for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {int t = a[lo]; a[lo] = a[hi]; a[hi] =t;
}
}//Merge a transformed descending sequence followed by an//ascending sequence
if (run[count] > left && a[run[count]] >= a[run[count] - 1]) {
count--;
}/** The array is not highly structured,
* use Quicksort instead of merge sort.*/
if (++count ==MAX_RUN_COUNT) {
sort(a, left, right,true);return;
}
}//These invariants should hold true://run[0] = 0//run[] = right + 1; (terminator)
if (count == 0) {//A single equal run
return;
}else if (count == 1 && run[count] >right) {//Either a single ascending or a transformed descending run.//Always check that a final run is a proper terminator, otherwise//we have an unterminated trailing run, to handle downstream.
return;
}
right++;if (run[count]
run[++count] =right;
}//Determine alternation base for merge
byte odd = 0;for (int n = 1; (n <<= 1) < count; odd ^= 1);//Use or create temporary array b for merging
int[] b; //temp array; alternates with a
int ao, bo; //array offsets from 'left'
int blen = right - left; //space needed for b
if (work == null || workLen < blen || workBase + blen >work.length) {
work= new int[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 (int last; count > 1; count =last) {for (int k = (last = 0) + 2; k <= count; k += 2) {int hi = run[k], mi = run[k - 1];for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) {if (q >= hi || p < mi && a[p + ao] <= a[q +ao]) {
b[i+ bo] = a[p++ +ao];
}else{
b[i+ bo] = a[q++ +ao];
}
}
run[++last] =hi;
}if ((count & 1) != 0) {for (int i = right, lo = run[count - 1]; --i >=lo;
b[i+ bo] = a[i +ao]
);
run[++last] =right;
}int[] t = a; a = b; b =t;int o = ao; ao = bo; bo =o;
}
}