二分法查找某个数据的在有序集合中的位置(必须要是有序集合)
二分法的理论
给定一个有序集合给定一个值,查询这个值是否在集合中,如果在,返回这个值的位置,如果不在,返回null
要知道中间位置就需要知道起始位置和结束位置,然后取出中间位置的值来和我们的值做对比
如果中间值正好等于要查找的数据直接返回位置
如果中间值大于我们的给定值,说明我们的值在中间位置之前,此时需要再次二分,因为在中间位置之前,有我们需要的数据的位置,此时结束位置的值应该是我们此时的中间位置。
反之,如果中间值小于我们给定的值,那么说明给定值在中间位置之后,此时需要再次将后一部分的值进行二分,因为在中间值之后,所以我们需要改变的值是开始位置的值,此时开始位置的值应该是我们此时的中间位置,直到我们找到指定值。
$array = [1,5,6,9,11,15,18,20,26,28,29,36,54,56,85,99,100];//给定原始有序集合
/**
*二分法获取指定值的位置
*/
function getNumKey($array,$num){
$arrayCount = count($array);//获取数组长度(总共有多少值)
$end = $arrayCount;//取数组长度作为结尾值
$middle = floor(($arrayCount/2)); //获取数组的中间的key值
$start = 0; //循环开始前取开始位置为0(因为有序数组的默认键值为0开始)
while($start
if($num == $array[$middle]){
return $middle+1;//如果集合的值正好等于中间值,直接返回
}elseif($array[$middle] < $num){
$start = $middle; //如果给定的值比选的中间的数据大,说明取中间值之后的集合,从新定义开始位置
$middle = floor((($start+$end)/2)); //重新定义中间值
}else{
$end = $middle; //如果给定的值比选的中间的数据大,说明取中间值之前的集合,从新定义结束位置
$middle = floor((($start+$end)/2)); //重新定义中间值
}
}
return null;
};
$result = getNumKey($array,26);