1. 标准二分查找
返回带查找元素key的下标。若没有key元素,则返回-1。注意:
1)while循环的条件是low<=high;
2) 每次迭代hi=mid-1 或lo=mid + 1
/**
* 二分查找,找到该值在数组中的下标,否则为-1
*/
static int binarySerach(int[] array, int key) {
int left = 0;
int right = array.length - 1;
// 这里必须是 <=
while (left <= right) {
int mid = (left + right) / 2;
if (array[mid] == key) {
return mid;
}
else if (array[mid] < key) {
left = mid + 1;
}
else {
right = mid - 1;
}
}
return -1;
}
2.查找第一个与key相等的元素
查找第一个相等的元素,也就是说等于查找key值的元素有好多个,返回这些元素最左边的元素下标。没有key时返回-1.
而返回第一个相等的位置:此时循环不变式可以表示为“[0, left)
所有元素小于val,而 (right, N-1]
所有元素都大于等于val”,这样当程序终止的时候我们arr[left]
就是第一个大于等于val的元素了。
static int findFirstEqual(int[] array, int key) {
int left = 0;
int right = array.length - 1;
// 这里必须是 <=
while (left <= right) {
int mid = (left + right) / 2;
if (array[mid] >= key) {
right = mid - 1;
}
else {
left = mid + 1;
}
}
if (left < array.length && array[left] == key) {
return left;
}
return -1;
}
3. 查找最后一个与key相等的元素
查找最后一个相等的元素,也就是说等于查找key值的元素有好多个,返回这些元素最右边的元素下标。
返回最后一个相等的位置:此时循环不变式可以表示为“[0, left)
所有元素小于等于val,而(right, N-1]
所有元素都大于val”,这样当程序终止的时候我们arr[right]
就是第一个小于等于val的元素了。
// 查找最后一个相等的元素
static int findLastEqual(int[] array, int key) {
int left = 0;
int right = array.length - 1;
// 这里必须是 <=
while (left <= right) {
int mid = (left + right) / 2;
if (array[mid] <= key) {
left = mid + 1;
}
else {
right = mid - 1;
}
}
if (right >= 0 && array[right] == key) {
return right;
}
return -1;
}
4. 正常二分,只不过返回时不是-1,而是被插入的位置
while (left <= right) {
if (arr[mid] == val) return mid;
else if (arr[mid] < val) left = mid + 1;
else right = mid - 1;
}
return right + 1;