时间复杂度:
- 最优时间复杂度:O(1)
- 最坏时间复杂度:O(logn)
原理与实现:
二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。
假设顺序表为升序:
- 取顺序表的中间位置元素【M=floor((first+last) / 2)或M=ceil((first+last) / 2)】若该元素为待查找元素(F),即(M=F)则查找成功。
- 若不是为待查找的元素,则用该中间位置元素与查找元素进行比较,将顺序表分为前后两个子表。如果待查找元素小于该中间元素(F<M),则在M的前子表(若F>M,则在右边)继续取该子表的中间位置元素。
- 重复1、2步骤,以此类推,直到满足条件查找成功,或者子表不存在,没有要查找的值。
非递归实现:
//非递归实现
function binary_search($arr, $item)
{
$count = count($arr);
if($count <= 0) {
return -1;
}
$first = 0;
$last = $count - 1;
do {
$middle = floor(($first + $last) / 2);
//$middle = ceil(($first + $last) / 2);
if($arr[$middle] == $item){
return $middle;
}elseif($arr[$middle] < $item) {
$first = $middle + 1;
}else{
$last = $middle - 1;
}
} while ($first <= $last);
return -1;
}
$arr = [5,17,18,20,31,44,54,55,67,89,345];
$search = 89;
$index = binary_search($arr, $search);
echo $index ? $arr[$index] : $index;
递归实现:
if(!function_exists('binary_search'))
{
function binary_search($arr, $item)
{
$count = count($arr);
if($count <= 0){
return false;
}
$middle = floor($count / 2);
if($arr[$middle] == $item){
return true;
}else{
if($arr[$middle] < $item){
return binary_search(array_slice($arr, $middle + 1), $item);
}else{
return binary_search(array_slice($arr, 0, $middle), $item);
}
}
}
}
$arr = [5,17,18,20,31,44,54,55,67,89,345];
$search = 89;
$is_exists = binary_search($arr, $search);
var_dump($is_exists);