sort()
.sort()调用的核心代码
private static <T> void binarySort(T[] a, int lo, int hi, int start,
Comparator<? super T> c) {
assert lo <= start && start <= hi;
if (start == lo)
start++;
for ( ; start < hi; start++) {
T pivot = a[start];
// Set left (and right) to the index where a[start] (pivot) belongs
int left = lo;
int right = start;
assert left <= right;
/*
* Invariants:
* pivot >= all in [lo, left).
* pivot < all in [right, start).
*/
while (left < right) {
int mid = (left + right) >>> 1;
if (c.compare(pivot, a[mid]) < 0)
right = mid;
else
left = mid + 1;
}
assert left == 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.
*/
int n = start - left; // The number of elements to move
// Switch is just an optimization for arraycopy in default case
switch (n) {
case 2: a[left + 2] = a[left + 1];
case 1: a[left + 1] = a[left];
break;
default: System.arraycopy(a, left, a, left + 1, n);
}
a[left] = pivot;
}
}
核心代码中的核心
while (left < right) {
int mid = (left + right) >>> 1;
if (c.compare(pivot, a[mid]) < 0)
right = mid;
else
left = mid + 1;
}
assert left == right;
该段代码的核心是找到pivot的插入位置,即找到第一个比pivot“大”的数。
“大”是实现compare定义的。如何定义如下
Arrays.sort(arr, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
@Override
public boolean equals(Object obj) {
return false;
}
});
其中return o2-o1为简写,01为待插入值,02为中间值,比较好理解的烦恼写法如下:
// 当需要升序排列时
if(o1<o2){// o1 o2 ,01在o2 前面 ,即向左收缩
return -1;
}
if(o1==o2){
return 0;
}
if(o1>o2){ // 应该是 o2 o1,o1在o2后,向右收缩
return 1;
}
更深一步的理解
二分查找最后“刹车”位置的“物理意义”
二分法进阶
- 给定一个升序,找到第一个比目标元素大的位置,无重复元素
- 给定一个升序,找到第一个比目标元素大的位置,有重复元素