二分查找
思路:不断从中间划分,不断缩小范围找到数字,提高效率。
*二分查找:整数二分 和 浮点数二分:
一.*整数二分模板:
while (l < r)//判断 最左边 < 最右边 当 最左边 = 最右边 时证明找到下标
{
int mid = (l + r ) / 2 ;//找到最中间的点。
if (a[mid] >= x)//先判断中间的数是不是比x大和x一样
r = mid;//比x大就先削去最右边,更新最右边
else
l = mid + 1;//比x小还不等于x就更新再 加 1
}
while (l < r)//判断 最左边 < 最右边 当 最左边 = 最右边 时证明找到下标
{
int mid = (l + r + 1 ) / 2;//一样 但是由于是先判断中间的数小于等于x,又因为程序运行时向下取整,所以+1避免死循环
if (a[mid] <= x)//先判断中间的数是不是比x小和x一样
l = mid;//比x小就先削去最左边,更新最左边
else
r = mid - 1;//比x大还不等于x就更新再 减 1
}
两个模板的差别在于一条线中查询最左点 或 最右点
例如:{1,2,2,3,4,5,6,7},查询数字为 2 的下标。
第一模板(最上方)是 1 ,第二模板 (最下方)是 2;
第一模板取最左: 先割去最右边 所以取最左;
第二模板取最右: 先割去最左边 所以取最右;
第二模板要l+r+1:关于向下取整,例如 l=1,r=2,那么此时(l+r)/ 2 == 1;mid==1,因为先割去左边 如果l=mid,就没变,就相当与一个死循环;
浮点数二分(这个简单):
例题:找x的平方根:
代码:
#include <iostream>
using namespace std;
int main()
{
double x;
cin >> x;
double r, l;
l = 0, r = x;
while (r - l > 1e-10)
{
double mid = (l + r) / 2;
if (mid * mid >= x)
r = mid;
else
l = mid;
}
cout << r;
return 0;
}
…没了;