# 二分查找
## 现实中的例子:
> 我们日常生活中,很多人应该有这种经历,朋友、同学或者同事淘了个宝贝,神秘兮兮的过来让大家猜多少钱,在约定一个价格范围之后(比如10-100),大家会七嘴八舌的猜起价格来:
>
> 「50」 「高了」
>
> 「30」 「低了」
>
> 「40」 「高了」
>
> 「36」 「对了」
>
> 如果我们用顺序遍历的逻辑,最差需要91次,才能猜到价格,现实生活中,没人会这么干,我们采用上面这种逻辑,只需要4次就猜到价格了,快了几十倍,而且数据量越大,优势越明显。
## 定义:
> 针对的是`一个有序的数据集合`(这点很重要),查找思想有点类似分治思想。每次都通过跟区间的中间元素对比,将待查找的区间缩小为之前的一半,直到找到要查找的元素,或者区间被缩小为 0。注意到二分查找针对的必须是已经排序过的有序数组,否则不能使用该算法。
![](https://box.kancloud.cn/c3d8eac05dc4ff04994221a33541034a_1142x819.png)
## 代码:
~~~
/**
* 二分查找
* @param $nums
* @return mixed
*/
function binary_search($nums,$num){//传入数组和需要查找的数据
return binary_search_internal($nums,$num,0,count($nums)-1);
}
function binary_search_internal($nums,$num,$low,$high){
if($low>$high){
return -1;//没有找到,即数组中不存在这个值
}
$mid = floor(($low+$high)/2);
if($num>$nums[$mid]){
return binary_search_internal($nums,$num,$mid+1,$high);
}elseif($num<$nums[$mid]){
return binary_search_internal($nums,$num,$low,$mid-1);
}else{
return $mid;
}
}
$nums = [1,2,3,4,5,6];
$index = binary_search($nums,5);
print $index;
~~~
## 总结:
1. 时间复杂度:O(logn)
2. 二分查找在线性表结构中的应用非常广泛
3. 针对有序数组
4. 二分查找适用于变动不是很频繁的静态序列集,如果序列集变动很频繁,经常进行插入删除操作,那么就要不断维护这个序列集的排序,这个成本也很高,因此,这种情况下就不适用二分查找了,比如我们的数据库查询,增删改查很频繁,显然不是通过二分查找来进行查询的,后面我们会讨论,如何针对动态变化的序列集进行查询操作。
- PHP操作集合
- 获取字符首字母
- PHP实现定时备份MySQL数据库
- PHP定时发送邮件
- PHP基本语法
- 总结
- 命名空间
- 错误抑制符
- 位运算符
- 原码,反码,补码
- traits
- PHP的反射机制
- const和define的区别
- 语法
- 常用的函数
- 1.变量及打印函数
- 2.引入文件
- 3.常量
- 4.错误处理
- 5.面向对象
- 数据结构与算法
- 结构
- 数组
- 索引
- 散列表(哈希表)
- 栈
- 队列
- 链表
- 算法
- 排序算法
- 插入排序
- 冒泡排序
- 选择排序
- 归并排序
- 快速排序
- 查找算法
- 二分查找
- 二分查找变形版本1:查询数据在序列中第一次出现
- 哈希算法
- 算法复杂度
- Smarty模板引擎
- composer
- yaf
- yaf的安装配置
- 其它
- Java
- JavaSE
- 1.Java发展及JDK安装配置
- 2.Eclipse的下载及安装
- 3.Java开发基础
- 虚拟机
- 2.编辑虚拟机设置
- 1.虚拟机下安装centos
- 3.安装vmtools
- Linux
- 1.vi和vim编辑器
- 2.开机、重启和用户登录注销
- 3.用户管理
- 4.用户组管理
- 5.用户和组的相关文件
- 6.linux运行级别
- 7.帮助指令
- 8.文件目录类指令
- 9.时间日期类
- 10.搜索查找类
- 11.压缩和解压缩
- 12.组管理和权限管理(难点,重点)
- 虚拟主机的配置
- phpstudy快捷配置
- 配置文件配置
- PHP面向对象高级特性
- SPL标准库(PHP标准库)
- PHP链式操作的实现
- 面向对象编程的基本原则
- 设计模式
- 基本的设计模式