有序条件下,才能查找算法
一.二分查找数组
(具备单调性,不必定严格单调)函数
(min 与max 是查找区间,经过不断缩小查找区间,来查找x的值)指针
min是头指针; max是尾指针;mid = (min + max) / 2;code
终止条件:min >= maxio
若是arr[mid] < x, min = mid + 1;ast
若是arr[mid] > x, max = mid - 1;class
若是arr[mid] == x, 找到结果基础
1.特殊状况(求最小最大解)搜索
查找最后的1
【min】【1】【1】【1】【1】【1】【0】【0】【0】【0】【0】
mid max
min:虚拟头指针
max:尾指针
mid = (min + max + 1) / 2
调整:
若是arr[mid] == 1, min = mid
若是arr[mid] != 1, max = mid - 1
若是min==max, 找到结果
2.特殊状况(求最小花费)
查找第一个1
【0】【0】【0】【0】【1】【1】【1】【1】【1】【1】【max】
min mid
min:头指针
max:虚拟尾指针
mid = (min + max) / 2
调整:
若是arr[mid] == 1,min = mid + 1;
若是arr[max] != 1, max = mid;
若是min==max,找到结果
二.三分查找
每次搜索范围缩小三分之一
求凹凸函数的极值问题
在二分查找的基础上,在右区间(或左区间)再进行一次二分,这样的查找算法称为 三分查找,也就是三分法。
三分查找一般用来迅速肯定最值。
(1)mid = (left + right) / 2;
(2)取右侧区间的中间值midmid,把区间分为三个小区间;midmid = (mid + right) / 2;
(3)比较mid与midmid谁最靠近最值,只须要肯定mid所在的函数值与midmid所在的函数值的大小。当最值为最大值时,mid与midmid中较大的那个天然更为靠近最值。最值为最小值时同理。
#include <stdio.h> #include <math.h> int binary_search1(int *num, int n, int x){ int min = 0, max = n - 1, mid; while(min <= max){ mid = (min + max) / 2; if(num[mid] == x) return mid; if(num[mid] < x) min = mid + 1; else max = mid - 1; } return -1; } int binary_search2(int *num, int n){//找到最后的1,Eg:11111000 int min = -1, max = n - 1, mid;//min是虚拟头指针; while(min < max){ mid = (min + max + 1) / 2;//+1防止出现min与mid重合的死循环; if(num[mid] == 0) max = mid - 1;//因为要找的是1,能够把后面的数据都扔掉了; else min = mid; } return min;//找不到自动等于-1; } int binary_search3(int *num, int n){//找到第一个1,Eg:00011111 int min = 0, max = n, mid;//max是虚拟尾指针,防止出现死循环; while(min < max){ mid = (min + max) / 2; if(num[mid] == 0) min = mid + 1;//因为要找数据1,能够把前面的数据扔掉了; else max = mid; } if(min == n) return -1;//数组中没有1; return min; } double f(double x){ static double a = 3.0, b = 2.0, c = 1.0; return a * x * x + b * x + c; } double ternary_search(double (*func) (double)){ #define EPSLON 1e-7 double L = -1000, R = 1000, m1, m2; while(fabs(L - R) > EPSLON){ m1 = (R - L) / 3.0 + L; m2 = 2.0 * (R - L) / 3.0 + L; if(func(m1) > func(m2)) L = m1; else R = m2; } #undef EPSLON return L; } int main(){ int num1[] = {1, 2, 3, 4, 5, 6}; printf("binary_search1(5): %d\n", binary_search1(num1, 6, 5)); int num2[] = {1,1,1,1,1,1,1,1,0,0,0,0,0,0,0}; printf("binary_search2(last one): %d\n", binary_search2(num2, 15)); int num3[] = {0,0,0,0,0,0,0,1,1,1,1,1,1,1,1}; printf("binary_search3(first one): %d\n", binary_search3(num3, 15)); printf("ternary_search(): %lf\n", ternary_search(f)); return 0; }
输出结果:
binary_search1(5): 4 binary_search2(last one): 7 binary_search3(first one): 7 ternary_search(): -0.333333