二分查找的模板有没有问题?能不能再简化?
注意:我说的二分查找不是简单的查找某个数,是类似于这样的:
在有序数组查找第一个>=x或<=x的数,有数组元素升序、降序,和查找左边界、右边界这些因素,
在有序数组查找第一个>=x或<=x的数,有数组元素升序、降序,和查找左边界、右边界这些因素,
在有序数组查找第一个>=x或<=x的数,有数组元素升序、降序,和查找左边界、右边界这些因素,
重要的事情说3遍
以下是我写的二分查找模板:
```c
int find(int x, int l, int r) // 求第一个 >=x(记作①) 或 <= x(记作②) 的元素的下标
{
/*
循环条件1:// 区间内存在不同的元素
循环条件2:// 区间长度 >=3 (为了防止在区间长度为2的时候出现死循环)
*/
while (a[l] != a[r] && r - l > 1)
{
int mid = (l + r) / 2;
if (a[mid] == x)
r = mid; // 左边界:r = mid; 右边界:l = mid;
if (a[mid] > x)
r = mid; // 升序:r = mid; 降序:l = mid;
if (a[mid] < x)
l = mid + 1; // 升序:l = mid + 1; 降序:r = mid - 1;
}
//无解时返回 -1
if (a[l] < x && a[r] < x) // ①:if条件里边用 < 号; ②:if条件里边用 > 号;
return -1;
// 不满足条件时,缩小区间
if (a[l] < x) // ①:if条件里边用 < 号; ②:if条件里边用 > 号;
l ++;
if (a[r] < x)
r --;
// 返回最优解
if (a[l] == a[r])
return l; // 左边界:return l; 右边界:return r;
if (a[l] < a[r]) // ①:if条件里边用 < 号; ②:if条件里边用 > 号;
return l;
else
return r;
}
```