二分查找
二分查找算法(英语:binary search algorithm),也称折半搜索算法(英语:half-interval search algorithm)、对数搜索算法(英语:logarithmic search algorithm),是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。
算法要求
- 必须采用顺序存储结构
- 必须按关键字大小有序排列
代码
循环(非递归)实现代码
/**
* 循环二分查找
* @param integer[] $nums 数组元素
* @param integer $target 查找元素
* @return 查找的的元素下标
*/
function search($nums,$target){
//最高点和最低点初始化
$low = 0;
$hight = sizeof($nums)-1;
//最高点大于等于最低点
while($low<=$hight){
//中间点等于一半
$mid = floor(($low + $hight)/2);
//中间点大于目标
if($nums[$mid]>$target){
//最高点 = 中间点 - 1,继续循环查找
$hight = $mid -1;
//中间点小于目标值
}elseif($nums[$mid]<$target){
//最低点 = 中间点 + 1,继续循环查找
$low = $mid + 1;
}else{
//中间点值与目标值一致,返回
return $mid;
}
}
}
$nums = [1,6,9,14,15,17,18,23,24,28,34,39,48,56,67,72,89,92,98,100];
$target = 28;
echo search($nums,$target);
递归实现代码:
/**
* 递归二分查找
* @param integer[] $nums 数组元素
* @param integer $target 查找元素
* @param integer $low 最低点
* @param integer $hight 最高点
* @return integer 查找到的元素
*/
function searchRecursive($nums,$target,$low = 0,$hight = 0){
//数组元素不为0,并且最高点不为0
if(sizeof($nums)>0 && $hight==0){
//初始最高点
$hight = sizeof($nums);
}
//最高点大于等于最低点
if($low <= $hight){
//中间点等于一半
$mid = floor(($low + $hight)/2);
//中间点值与目标值一致,返回
if($nums[$mid] == $target){
return $mid;
//中间点大于目标
}elseif($nums[$mid]>$target){
//最高点 = 中间点 - 1,继续递归查找
return searchRecursive($nums,$target,$low,$mid-1);
}else{
//最低点 = 中间点 + 1,继续递归查找
return searchRecursive($nums,$target,$mid+1,$hight);
}
}else{
echo 'meiyou';
}
}
$nums = [1,6,9,14,15,17,18,23,24,28,34,39,48,56,67,72,89,92,98,100];
$target = 28;
echo searchRecursive($nums,$target);