在一个有序数组中查找具体的某个数字n,(数据必须是有序的),可以使用二分查找。
二分查找的定义:
二分查找是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是目标值,则搜索过程结束;如果目标值大于或小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且同样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这个算法每一次比较都使搜索范围减半。
二分查找的过程。
本列中假设有10个元素,最左边的下标用 left 来表示,最有右边的下标用 right 来表示。中间元素的下标用 mid 来表示,mid = (left + right)/2 ,来表示。
本例中假设要查找的元素是7,这时 mid 比我们要查找的元素小,这时我们就把 mid 左边的数舍弃,查找范围就是 mid 的右边,查找一次之后,范围缩小了一半。这时我们进行第二次二分查找,这时 left 变成 mid +1 的位置进行第二次二分查找.
然后用新的左下标和右下标算出新的平均值。mid = (5+9)/2 = 7;
此时,left的下标是5,锁定的元素是6,right的下标是6,锁定的元素是7。此时 mid =(5+6)/2 = 5 ;
注意mid表示的是下标,不是元素。
总结一下:二分查找是通过想查找的元素(n)和mid(平均值)的比较,当 n> arr[mid] 时,left = mid +1;因为 mid 是下标,所以需要数组里查找mid 锁定元素来和 n 进行比较。当 n <arr[mid]时,
right = mid -1;当n = arr[mid]是就找到了这个元素,下标是mid.接下来就是总的代码。这里写两种办法。第一种通过循环的方式。
这个代码还是有点问题,因为 left right 加起来可能会溢出,一旦超出范围时,就会有溢出,溢出之后就不是平均值了。我们不是通过两个变量相加,而是通过把多余的/2在拿到我们left 变量当中去,这样的话只要right 没有溢出的话,left 就一定不会溢出。
接下来介绍函数的办法,我们自定义二分查找的函数为 binary_search。
这里我们在介绍一种错误,就是把 mid 的求值放在循环的外面,mid 的求取一定在循环的里头,不然下一次二分查找的时候,不会根据left right 求 mid ,构不成二分查找。最后我们我们把最后的代码放出,才艺不精,敬请谅解。如有错误,请及时指出,不吝赐教,天高海阔路漫长,我们来日方休,回见。