php 二分查找字符串,PHP算法——二分查找

二分查找

二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。

bVbuR1v?w=563&h=621

算法要求

1、必须采用顺序存储结构。

2、必须按关键字大小有序排列。

算法步骤

其实,二分查找也还是比较容易理解的,大概就是一分为二,然后两边比较,保留有效区间,继续一分为二查找,直到找到或者超出区间则结束,所以二分查找的基本步骤是:

1、确定要查找的区间

2、确定要二分时的参照点

3、区间内选取二分点

4、根据二分点的值,综合左右区间情况以及求解的目的,舍去一半无用的区间

5、继续在有效区间重复上面的步骤

代码示例

这里主要用非递归和递归两种实现方式查找,代码如下:

1、非递归查找

/*

* 二分查找(也叫折半查找)--非递归

* array $arr 待查找区间

* int $number 查找数

* int 返回找到的键

*/

public function binarySearch($arr,$number){

//待查找的区间不为数组或为空,则返回-1

if(!is_array($arr) || empty($arr)){

return -1;

}

sort($arr); //二分查找关键点

$len=count($arr);

$lower=0;

$high=$len-1;

//低点小于高点,则退出

while($lower<=$high){

//以中间点作为参照点比较

$middle=intval(($lower+$high)/2);

if($arr[$middle]>$number){

//查找数比参照值小,舍去右边

$high=$middle-1;

}else if($arr[$middle]

//查找数比参照值大,舍去左边

$lower=$middle+1;

}else{

//查找数与参照点相等,则返回

return $middle;

}

}

return -1;

}

2、递归查找

/*

* 二分查找(也叫折半查找)--递归

* array $arr 待查找区间

* int $number 查找数

* int $lower 低点

* int $high 高点

*/

public function binarySearchRecursion($arr,$number,$lower,$high)

{

//待查找区间如果不是数组或为空,返回-1

if(!is_array($arr) || empty($arr)){

return -1;

}

sort($arr);

$len=count($arr);

$middle=intval(($lower+$high)/2);

if($arr[$middle]>$number){

//查找数比参照值小,舍去右边

return $this->binarySearchRecursion($arr,$number,0,$middle-1);

}elseif($arr[$middle]

//查找数比参照值大,舍去左边

return $this->binarySearchRecursion($arr,$number,$middle+1,$high);

}else{

//查找数与参照值相等,则返回

return $middle;

}

//找不到,则返回-1

return -1;

}

算法使用

需求是在待查找区间$arr中,找出$number所在的位置,调用算法如下:

//待查找区间的数组

$arr=array(1,2,3,4,5,6,7,10,12,14,18,16,20);

//非递归查找$arr中25所在的位置

$binaryKey=$this->binarySearch($arr,25);

//递归查找$arr中12所在位置

$binarySearchRecursionKey=$this->binarySearchRecursion($arr,1,12,count($arr)-1);

//打印输出

print_r($binaryKey);

echo '//';

print_r($binarySearchRecursionKey);

输出结果

-1//8

时间复杂度分析

在有序数组中如果用暴力的算法去查找,也就是逐个遍历比较,那么时间复杂度是O(n);但是,用二分查找后,因为每次可以舍去一半查找区间,所以会将时间复杂度减少到O(logn),算法更优。 (关于算法的时间复杂度与空间复杂度详细解释)

相关资料

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值