二分查找这个算法效率算是相当高的了,如此简单又高效的算法当然值得我们学习和研究!
首先,我们来引入一道要求二分查找的题:
其次要明确的一点是二分查找是建立在已经有序的序列上的!接下来我们来分析一下这个题该怎么解!
我们先假设数组 v 中存的数是这样的:
其中,为了方便计算,我们使对应的下标等于对应的值!然后,定义分别定义整型变量 left 和 right 指向 v 的左右边界的下标。
然后取 mid = (left + right) / 2;
假如我们要找的 x = 5,这样,我们比较一下 v[mid] 和 x 的值,3 < 5,所以,我们令 left = mid + 1;然后,left 指向 4 的位置,再求一次 mid
指向关系就变成了现在这样,再比较 v[mid] 和 x 的值,我们发现,找到了!看见没,效率就是这么高!
最后来补上我们的源代码:
#include <stdio.h> int bin_search(int arr[], int x, int left, int right) { while (left <= right) { int mid = (right + left) / 2; if (arr[mid] > x) right = mid - 1; else if (arr[mid] < x) left = mid + 1; else return mid; } return -1; } int main(void) { int v[] = {0,1,2,3,4,5,6,7,8,9}; int ret = 0; ret = bin_search(arr, 5, 0, 9); printf("%d\n",ret); getchar(); return 0; }
是不是不难呢但是,程序还有一个隐藏的小问题,那就是 mid 的求取方法;现在的求取方法显然不太好,比如当 left 和 right 足够大时在相加可能会导致溢出的问题!
所以,针对这个问题,我们又把这里优化了一下:
mid = (right - left) / 2 +left;
这条语句在数学上是完全等价于我们的 mid = (left + right) / 2; 的,但是在计算机里,我们不难看出它们之间的区别,自己想想吧!
最后再加上递归实现:
int bin_search_2(int arr[], int x, int left, int right) { /*递归实现*/ if (left > right) return -1; int mid = (right - left) / 2 + left; if (arr[mid] == x) { return mid; } else if (arr[mid] > x) { right = mid - 1; return bin_search_2(arr, x, left, right); } else { left = mid + 1; return bin_search_2(arr, x, left, right); } }
【算法】二分查找
最新推荐文章于 2022-07-10 19:39:16 发布