You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
/* * 这个函数的目的是为了查找连续递增(这个递增包括相等,但是总的趋势是增) * 或者是严格递减(也就是不能包含相等)这样做的原因是为了排序的稳定性 * 如果是严格递减,那么就会反转过来 */privatestatic <T> intcountRunAndMakeAscending(T[] a, intlo, inthi,
Comparator<? superT> c) {
assertlo < hi;
intrunHi = lo + 1;
if (runHi == hi)
return1;
// Find end of run, and reverse range if descending// 先比较前两个的元素的大小,来确定接下来的趋势if (c.compare(a[runHi++], a[lo]) < 0) { // Descendingwhile (runHi < hi && c.compare(a[runHi], a[runHi - 1]) < 0)
runHi++;
reverseRange(a, lo, runHi);
} else { // Ascendingwhile (runHi < hi && c.compare(a[runHi], a[runHi - 1]) >= 0)
runHi++;
}
returnrunHi - lo;
}
/* 这个就是二分插入了,也就是已经有了一段有序的区间,还有剩下的部分不是有序的,那么 * 循环将剩下的部分利用二分查找找到应该插入的位置 */privatestatic <T> voidbinarySort(T[] a, intlo, inthi, intstart,
Comparator<? superT> c) {
assertlo <= start && start <= hi;
// 如果start等于最小的下标,那么第一个元素可以认为是有序的if (start == lo)
start++;
/* 开始循环 将[start, hi) 逐个插入排序, * start代表不在有序区间的第一个元素下标 * 也就是说[start, hi) 这个区间不是有序的 */for ( ; start < hi; start++) {
Tpivot = a[start];
// Set left (and right) to the index where a[start] (pivot) belongsintleft = lo;
intright = start;
assertleft <= right;
/* * Invariants: * pivot >= all in [lo, left). * pivot < all in [right, start). * 这个部分其实就是找到第一个大于privot的下标 * 这个部分其实是有难度的,二分查找有很多变种 * 比如 数据从小到大,查找第一个大于某个数key的下标位置 * 查找第一个大于某个数key的下标位置 * 下一篇会写 */while (left < right) {
intmid = (left + right) >>> 1;
if (c.compare(pivot, a[mid]) < 0)
right = mid;
elseleft = mid + 1;
}
// 循环结束之后left == right 那么也就是要找的下标位置assertleft == right;
/* * The invariants still hold: pivot >= all in [lo, left) and * pivot < all in [left, start), so pivot belongs at left. Note * that if there are elements equal to pivot, left points to the * first slot after them -- that's why this sort is stable. * Slide elements over to make room for pivot. */intn = start - left; // The number of elements to move// Switch is just an optimization for arraycopy in default caseswitch (n) {
case2: a[left + 2] = a[left + 1];
case1: a[left + 1] = a[left];
break;
// 这边就相当于left到start前一位的元素先后移动一位,空出来一个位置给privot, 就这样一直到全部插入完, 上面case 2 和case 1z只是简单版copydefault: System.arraycopy(a, left, a, left + 1, n);
}
a[left] = pivot;
}
}
java8种Arrays.sort使用的是TimSort方法,其实从总体来看是我个人看法是归并排序的优化版,先不说作用,先从代码说起
二分查找参见 二分查找
python 版Timsort的各个设计的来源
The text was updated successfully, but these errors were encountered: