php算法 - 二分查找 2019-09-23
二分查找也称折半查找,它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。
查找过程:
首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
算法要求:
1.必须采用顺序存储结构。
2.必须按关键字大小有序排列。
其实,说白了 ,就是当我们有一个这样的数组[1,5,9,10,11,16,23,25,31,35,48,52,56,59,60,67];
我们要找出某个值的位置时,例如16在哪个位置时,应该如何快速找到他?如果从头往后找,或者从尾往前找,是不是很慢?如果数组N长,我们的查找就有可能是N次。
而二分查找就不一样了。
直接折半。比如上面例子数组有16个元素。 16/2=8那就是从 arr[8] 这个位置开始找。首先我们判断16是否等于 arr[8]这个值 如果等于返回,不等于则判断是否大于/小于 ,如果大于,则往上找,小于则往下找。
按照上面例子。
像上面例子,找到为16的过程仅仅只有 3次就能找到。如果我们仅仅使用循环,则要循环到第6次才能真正找到他的位置。
OK,我们贴代码(我上的是递归版,循环版的大家可以自行模仿写一个,也可以百度查找demo)
/** * * @param array $container 数组 * @param type $search要找的数据 * @param type $low 开始位置 * @param type $top结束位置 * @return string 返回 如果找到则是位置的key,如果没找到则是返回没找着哦 */ function BinaryQueryRecursive(array $container, $search, $low = 0, $top = 'default') { $top == 'default' && $top = count($container); if ($low <= $top) { $mid = intval(floor($low + $top) / 2); if (!isset($container[$mid])) { return '没找着哦'; } if ($container[$mid] == $search) { return $mid; } if ($container[$mid] < $search) { return BinaryQueryRecursive($container, $search, $mid + 1, $top); } else { return BinaryQueryRecursive($container, $search, $low, $mid - 1); } } } $container = [1, 5, 9, 10, 11, 16, 23, 25, 31, 35, 48, 52, 56, 59, 60, 67]; echo BinaryQueryRecursive($container, 16);
给大家个图自己看看逻辑是这样的,例子显示搜39,第一次是蓝色这条的搜索,第二次是橙色,第三次绿色。三次完成。