Бинарный поиск
Задачу бинарного поиска сформулируем так. Есть функция-предикат `f`, принимающая на отрезке от `A` до `X` значение 0, а на отрезке от `X` до `B` значение 1. Найти значение `X`, т.е. минимальное значение `X`, для которого `f(X)=1`.
Рассмотрим значение функции `f` в середине отрезка `[A,B]`. В случае если оно равно 0, то можно отбросить левую половину отрезка, а в случае 1 – правую. Таким образом длина отрезка для поиска `X` уменьшается вдвое. В случае вещественного диапазона для поиска решения с точностью `ε` требуется `log_2\ ((B-A)/ε)` шагов. В случае дискретных значений для поиска потребуется `log_2(B-A+1)` шагов.
double bsrch(double a, double b, double eps, bool (*f)(double))
{ double c;
while(b-a>=eps)
{ c=(b+a)/2;
if(f(c)) b=c;
else a=c;
}
return b;
}
Для дискретного случая программа выглядит аналогично.
int bsrch(int a, int b, bool (*f)(int))
{ int c;
while(a<b)
{ c=(b+a)/2;
if(f(c)) b=c;
else a=c+1; //
}
return b;
}
Пусть требуется найти индекс первого нулевого элемента в упорядоченном по возрастанию массиве.
int m[100]; //
int n; //
int k; //
bool f0(int i)
{ return m[i]>=0;
}
...
k=bsrch(0,n,f0); //
//
if(k==n || m[k]!=0)
printf("Нет элемента\n");
else
printf("%d\n",k);