二分查找的定义

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

算法的要求

从上面的定义我们可以知道,满足该算法的要求必须如下两点:

必须采用顺序存储结构。

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

算法的步骤

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

确定要查找的区间

确定要二分时的参照点

区间内选取二分点

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

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

算法源码

这里,我主要采用递归和非递归两种方法实现,具体如下:

首先第一种是非递归的算法实现,算法如下:

/**

* 二分查找算法

* @param array $arr 待查找区间

* @param int $number 查找数

* @return int 返回找到的键

*/

function binary_search($arr, $number) {

// 非数组或者数组为空,直接返回-1

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

return -1;

}

// 初始变量值

$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] < $number) {

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

$lower = $middle + 1;

} else {

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

return $middle;

}

}

// 未找到,返回-1

return -1;

}

然后第二种是递归的算法实现,算法如下:

/**

* @param array $arr 待查找区间

* @param int $number 查找数

* @param int $lower 区间最低点

* @param int $high 区间最高点

* @return int

*/

function binary_search_recursion(&$arr, $number, $lower, $high) {

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

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

// 最低点比最高点大就退出

if ($lower > $high) {

return -1;

}

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

// 查找数比参照点大,舍去左边继续查找

return binary_search_recursion($arr, $number, $middle + 1, $high);

} elseif ($number < $arr[$middle]) {

// 查找数比参照点小,舍去右边继续查找

return binary_search_recursion($arr, $number, $lower, $middle - 1);

} else {

return $middle;

}

}

算法的使用

需求是在一个排列好的区间($arr)中,查找一个数($number)的所在位置,所以,调用算法查找如下:

// 待查找区间

$arr = [1, 3, 7, 9, 11, 57, 63, 99];

// 非递归查找57所在的位置

$find_key = binary_search($arr, 57);

// 递归查找57所在的位置

$find_key_r = binary_search_recursion($arr, 57, 0, count($arr));

// 输出打印

print_r($find_key);

print_r($find_key_r);

时间复杂度分析

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

最后

又到了无聊的客套话时间,老规律,有问题直接留言,有想法直接说,有错误直接提出来,我都会及时回复的,谢谢。

php查询算法,PHP算法之二分查找相关推荐

  1. 经典算法之左边界二分查找法(俗称左边界二分搜索法)

    经典算法之左边界二分查找法(俗称左边界二分搜索法) 文章目录 经典算法之左边界二分查找法(俗称左边界二分搜索法) 前言 一.什么左边界二分查找法? 二.代码实现 总结 前言 就算法而言,我们主要学习的 ...

  2. 经典算法之右边界二分查找法(俗称基本右边界二分搜索法)

    经典算法之右边界二分查找法(俗称基本右边界二分搜索法) 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 经典算法之右边界二分查找法(俗称基本右边界二分搜索法) 前言 一.什 ...

  3. php二分查找算法时间复杂度,一个运用二分查找算法的程序的时间复杂度是什么...

    一个运用二分查找算法的程序的时间复杂度是"对数级别".二分查找是一种效率较高的查找方法,算法复杂度即是while循环的次数,时间复杂度可以表示"O(h)=O(log2n) ...

  4. 【算法】详解二分查找算法(思路很简单,细节是魔鬼)

    我周围的人几乎都认为二分查找很简单,但事实真的如此吗?二分查找真的很简单吗?并不简单.看看 Knuth 大佬(发明 KMP 算法的那位)怎么说的: Although the basic idea of ...

  5. C++ 算法基础课 01 —— 基础算法_快速排序/归并排序/二分查找/高精度

    文章目录 1 排序 1.1 快速排序(难在划分) 1.1.1 模板 1.1.2 习题1 -- 785.快速排序 1.1.3 习题2 -- 786.第k个数(快速选择算法) 1.2 归并排序(难在合并) ...

  6. LeetCode算法题4:二分查找及扩展应用

    文章目录 前言 一.二分查找 二.第一个错误的版本 三.搜索插入位置 总结 前言 Leetcode算法系列:https://leetcode-cn.com/study-plan/algorithms/ ...

  7. 算法与数据结构之二分查找

    一.两道LeetCode题 首先来两道算法题举例,来初步探讨二分查找 278.First Bad Version 先贴上代码 // Forward declaration of isBadVersio ...

  8. 小白的算法初识课堂(part1)--二分查找法

    学习笔记 学习书目:<算法图解>- Aditya Bhargava 二分查找法 算法是一组完成任务的指令,任何代码片段都可视为算法.二分查找是一种算法,其输入是一个有序的元素列表(必须有序 ...

  9. 【数据结构与算法】task3 排序二分查找

    排序 参考:https://github.com/wangzheng0822/algo/tree/master/python 归并排序 def merge_sort(a):_merge_sort_be ...

  10. python实现二分查找_数据结构和算法:Python实现二分查找(Binary_search)

    在一个列表当中我们可以进行线性查找也可以进行二分查找,即通过不同的方法找到我们想要的数字,线性查找即按照数字从列表里一个一个从左向右查找,找到之后程序停下.而二分查找的效率往往会比线性查找更高. 一. ...

最新文章

  1. linux top 报错 TERM environment variable not set.
  2. xgboost模型在centos系统下的可视化
  3. Yii的GridView
  4. 128位加密SSL证书
  5. 阿里云肖力:跳过量变过程的安全质变
  6. avr单片机教程 csdn_从古老的attiny85升级到新的AVR 1系列attiny412教程
  7. java一键生成《数据库设计文档》
  8. linux打开word、excel等
  9. 2015年度APP分类
  10. c语言一个笼子里关了鸡和兔子,成年后的你是否还质疑 古人为什么把鸡和兔子关在一个笼子里...
  11. 第一次用python写爬虫
  12. 双重福利:计算机图书满100减50+满99 减10叠加券,更有抽奖送书活动,点击查看!...
  13. DW-概率统计打卡task01
  14. C++ 读取TXT文件中的数据 每一行空格符相隔的数据单独取出
  15. dgl edges_浏览器趋势2016年10月:Microsoft Edges下降
  16. 【Node.js】nvm的常用操作
  17. java ppt 绘图,PPT图片别再直接插入,这样处理一下,让你的PPT秒变高逼格
  18. 用计算机打字怎么打括号,键盘的输入问题
  19. CMMI5个等级和22个过程域
  20. 【vivado学习六】 Vivado综合

热门文章

  1. 设计模式之单例设计模式(饿汉式)
  2. Oracle中的Rowid
  3. 解决 Oralce 执行set autotrace on时的SP2-0618和SP2-0611错误
  4. mysql索引要点_mysql表索引的一些要点_MySQL
  5. 解决Windows安装TensorFlow报错:ERROR: Cannot uninstall 'wrapt'问题
  6. creo导入特征怎么实体化_Creo/Proe云图抄数牙刷抄数造型
  7. java xml 验证工具_验证xml格式
  8. notepad++ c语言编译,Notepad++編譯和運行C語言 (GCC)
  9. Dubbo 在 K8s 下的思考
  10. 格莱泽检验matlab,计量经济学实验指导书