二分法
二分法查找,也称为折半法,是一种在有序数组中查找特定元素的搜索算法。
二分法查找的思路如下:
(1)首先,从数组的中间元素开始搜索,如果该元素正好是目标元素,则搜索过程结束,否则执行下一步。
(2)如果目标元素大于/小于中间元素,则在数组大于/小于中间元素的那一半区域查找,然后重复步骤(1)的操作。
(3)如果某一步数组为空,则表示找不到目标元素。
二分法查找的时间复杂度O(logn)。
int类型
int LowerBound(int a[], int target, int left, int right)
{
while(right >= left)
{
int mid = left + (right - left) / 2;//防止left + right 溢出
if(a[mid] > target) right = mid - 1;
else if(a[mid] < target) left = mid + 1;
else if(a[mid] == target) return mid;
}
return -1;//表示right<left 的情况 没找到target的情况
}
- 传递一个 left right如果为数组的下标,就会查找到target 元素的下标
double类型
#include<stdio.h>
#define eps 1e9
int binarysearch(int l[],double target ,double left ,double right)
{
while(right-left >eps)
{
double mid=left + (rght-left)/2.0;
if(l[mid]==target)
return mid;
if(l[mid]>target)
left=mid+1;
if(l[mid]<target)
right=mid-1;
}
return -1;
}
例题
题目背景
tz大佬从遥远的喜马拉雅山挖出了一个N阶的函数,为了研究这个神奇的函数,tzdalao把函数拉到了编程俱乐部。
题目描述
这棵函数是N次函数,经过观察发现,在闭区间[l,r]内函数存在一个极大值点,请求出这个极大值点x。
输入格式:
第一行,一个正整数N和两个实数l、r,表示闭区间范围。
第二行,N+1个实数,从左到右依次表示函数的系数。
输出格式:
输出x的值,四舍五入保留5位小数。
输入样例#1:
3 -0.9981 0.5
1 -3 -3 1
输出样例#1:
-0.41421
说明
上述样例是n = 3,x3-3x2 - 3x + 1
include <stdio.h>
#include <math.h>
double a[100] = {0}, n, ans1, mid;
double y(double x)//求一阶导数
{
double j = n-1, ans = 0;
for(int i = 0 ; i < n && j >= 0; i++, j--)
{
ans += a[i]*pow(x, j);
}
return ans;//返回一阶导数的值
}
int main(void)
{
double temp;
double l, r;
scanf("%lf%lf%lf", &n, &l, &r);
temp = n;
for(int i = 0; i <= n; i++)
{
scanf("%lf", &a[i]);
a[i] = a[i]*temp;//求一阶导数的系数
temp -= 1;
}
while(r - l > 0.0000001)//double类型
{
mid = (r+l)*1.0/2;
if(y(mid) > 0) l = mid;//调用函数,把mid的值传进去导数代数式
else r = mid;
}
printf("%.5lf", mid);
return 0;
}