二分查找算法思想非常简单,就是折半查找一个有序序列,在这里,我用二分查找一个顺序排列的整形数组。若用C实现的话我们需要注意以下几个方面:
1.如何判断查找完成,定义返回值含义,定义退出循环条件
2.如何处理边界问题,例如1 2 3 这个序列,当我们要查找1或者3时,会不会使程序出现BUG
3.对于数列来说,我们通常用整形存储其下标,二分查找若取下标中间数,则会出现什么样的问题?这些问题是否会影响我们的查找,若有问题,则应该如何规避?
通常情况,作为一个初学者,我甚至觉得二分查找过于简单,不值一提,最近经过思考,二分查找算法对于理论的要求并不是很高,但是若要把它变为有可行性的程序代码,则我们需要思考诸多的细节,否则这个代码写出来则是错误百出的。
如何解决第一个问题,因为我们了解的二分查找的思路其实就是折半查找,要有左边界与右边界我们才能确定中间元素,当左边界与右边界重合的时候,这时查找对象就变为一个元素的,若它也不是索要查找的对象,那么在所查找的集合中便没有所需的元素。这样我们就清楚地定义出来了所需参数,以及退出查找的条件。我们需要一个左边界以及右边界,还有中间元素,若右边界比左边界小(左比右大)时,退出循环,返回异常。若否,则执行 查找语句。
这里的查找语句如何设计呢,若不结合第2,3个问题,我们可以随手写出代码:
while(left<=right) { mid=(left+right)/2; if(x>mid) left=mid; else if(x<mid) right=mid; else return mid; } return error;
显然这样做的话实在是太理想了,按出数学的思路,这样做是根本取不到边界的,如果考虑到C语言中的整形会自动舍弃小数,那么对于左边界是我们这样写是完全可以的,但是右边界是永远都不会取到的,如果取中间值取到非整数,是否会在其他方面影响到我们的查找结果呢,答案是不会的,若产生自动舍弃小数的状况,仅仅只会影响我们在一个有序序列中查找元素的位置与分段查找所分段的长度,并不会影响我们的查找结果,如果要解决边界问题,我们可以使分段所产生的边界偏移,由于mid元素已经被判断过了,所以我们分段的时候段的边界可以直接舍弃掉mid元素,使得边界为mid+1或mid-1,这样我们便完成了整型数组的二分查找,实现代码如下:
#include <stdio.h>//二分查找算法即测试用例 int BinySerch(int *arr, int x, int lengh)//设计参数,由于是整形数组,所以我们必须传递他 { //长度否则数组传参时会发生降级 int left = 0, right = lengh - 1; int mid ; while (left <= right) { mid = left + (right - left) / 2; if (x < arr[mid]) { right = mid - 1; } else if (x > arr[mid]) { left = mid + 1; } else { return mid; } } return -1; } int main()//测试用例 { int x = 0; int arr[11] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int lengh = sizeof(arr) / sizeof(arr[0]); for (int i = 0; i < 12; i++) { printf("%d ",BinySerch(arr, i, lengh)); } system("pause"); return 0; }
若有不足之处,希望批评指正
本文出自 “pawnsir的IT之路” 博客,请务必保留此出处http://10743407.blog.51cto.com/10733407/1739541
原文地址:http://10743407.blog.51cto.com/10733407/1739541