二分查找又称折半查找,只对有序的数组有效。
优点是比较次数少,查找速度快,平均性能好,占用系统内存较少;
缺点是要求待查表为有序表,且插入删除困难。
因此,折半查找方法适用于不经常变动而查找频繁的有序列表。
 
一、算法思想
首先,将表中间位置记录的值与查找值比较,如果两者相等,则查找成功;否则利用中间位置将表分成前、后两个子表,如果中间位置的值大于查找值,则进一步查找前一子表,否则进一步查找后一子表。
重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
具体做法如下:
(1) 将数组的第一个位置设置为下边界(0)。
(2) 将数组最后一个元素所在的位置设置为上边界(数组的长度减 1)。
(3) 若下边界等于或小于上边界,则做如下操作:
a. 将中点设置为floor((上边界+下边界)/2)。
b. 如果中点的元素小于查询的值,则将下边界设置为中点元素所在下标加1。
c. 如果中点的元素大于查询的值,则将上边界设置为中点元素所在下标减1。
d. 否则中点元素即为要查找的数据,可以进行返回。
 
二、PHP的二分查找算法实现
1、递归方式
// 数组为升序排序
function binarySearch($arr, $search) {
    $start = 0;
    $end = count($arr) - 1;
    while ($start <= $end) {
        $mid = floor(($start + $end) / 2);
        // echo "当前的中点:" . $mid;   // 用于显示每次重新计算后得到的中点
        if ($search == $arr[$mid]) {
            return $mid;
        } elseif ($search < $arr[$mid]) { // 所查值小于中间值,则在$mid左边的值中查找
            $end = $mid - 1;
        } else { // 所查值大于中间值,则在$mid右边的值中查找
            $start = $mid + 1;
        }
    }
    return -1; // 查找失败
}
2、非递归方式
// 数组为升序排序
function binSearch($arr, $start, $end, $search) {
    if ($start <= $end) {
        $mid = floor(($start + $end) / 2);
        if ($search == $arr[$mid]) {
            return $mid;
        } elseif ($search < $arr[$mid]) {
            return binSearch($arr, $start, $mid - 1, $search);
        } else {
            return binSearch($arr, $mid + 1, $end, $search);
        }
    }
    return -1;
}
 
三、计算连续重复次数
function countDuplicate($arr, $search) {
    $count = 0;
    $position = binarySearch($arr, $search);
    if ($position > -1) {
        $count++;
        for ($i = $position - 1; $i > 0; $i--) {
            if ($arr[$i] == $search) {
                $count++;
            } else {
                break;
            }
        }
        for ($i = $position + 1; $i < count($arr); $i++) {
            if ($arr[$i] == $search) {
                $count++;
            } else {
                break;
            }
        }
    }
    return $count;
}
 
// 测试
$arr = array(1, 2, 4, 4, 4, 39, 4, 4, 4, 4, 78, 33, 69);
$cnt = countDuplicate($arr, 4);
echo $cnt;    // 4
我们可以看到,示例中数组有3个连续的4和4个连续的4,而结果为4。
这是因为这个函数一开始调用 binSearch( ) 函数来查找指定的值。如果在数组中能找到这个值,这个函数就通过两个循环来统计这个值连续重复出现的次数。
第一个循环向下遍历数组,统计找到的值出现的次数,当下一个值与要查找的值不匹配时则停止计数。
第二个循环向上遍历数组,统计找到的值出现的次数,当下一个值与要查找的值不匹配时则停止计数。

数据结构与算法之PHP查找算法(二分查找)的更多相关文章

  1. Java中常用的查找算法——顺序查找和二分查找

    Java中常用的查找算法——顺序查找和二分查找 神话丿小王子的博客 一.顺序查找: a) 原理:顺序查找就是按顺序从头到尾依次往下查找,找到数据,则提前结束查找,找不到便一直查找下去,直到数据最后一位 ...

  2. 递归分治算法之二维数组二分查找(Java版本)

    [java] /** * 递归分治算法学习之二维二分查找 * @author Sking 问题描述: 存在一个二维数组T[m][n],每一行元素从左到右递增, 每一列元素从上到下递增,现在需要查找元素 ...

  3. C语言查找算法之顺序查找、二分查找(折半查找)

    C语言查找算法之顺序查找.二分查找(折半查找),最近考试要用到,网上也有很多例子,我觉得还是自己写的看得懂一些. 顺序查找 /*顺序查找 顺序查找是在一个已知无(或有序)序队列中找出与给定关键字相同的 ...

  4. 【算法训练营day1】LeetCode704. 二分查找 LeetCode27. 移除元素

    [算法训练营day1]LeetCode704. 二分查找 LeetCode27. 移除元素 LeetCode704. 二分查找 题目链接:704. 二分查找 初次尝试 看到题目标题是二分查找,所以尝试 ...

  5. 【PHP数据结构】线性查找与二分查找

    欢迎来到查找的世界,在学习完各种数据结构之后,总算走到了这一步,不知道大家有什么感想呢?反正我是边学边忘,现在让我去说说图的那几个算法还是在蒙圈的状态中.不过学习嘛,就是一步一步的来,暂时搞不懂的东西 ...

  6. List<T>线性查找和二分查找BinarySearch效率分析

    今天因为要用到List的查找功能,所以写了一段测试代码,测试线性查找和二分查找的性能差距,以决定选择哪种查找方式. 线性查找:Contains,Find,IndexOf都是线性查找. 二分查找:Bin ...

  7. Java顺序查找、二分查找

    Java顺序查找.二分查找   查找算法中顺序查找算是最简单的了,无论是有序的还是无序的都可以,只需要一个个对比即可,但其实效率很低. 顺序查找 动图演示 详细代码 // 顺序查找 public st ...

  8. Java基础知识强化60:经典查找之二分查找

    1. 二分查找       二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表. 比较 ...

  9. 【Java数据结构与算法】简单排序、二分查找和异或运算

    简单排序 选择排序 概念 首先,找到数组中最小的那个元素,其次,把它和数组的第一个元素交换位置(如果第一个元素就是最小的元素那么它就和自己交换).再次,在剩下的元素中找到最小的元素,将它与数组的第二个 ...

  10. 各种查找算法的选用分析(顺序查找、二分查找、二叉平衡树、B树、红黑树、B+树)

    目录 顺序查找 二分查找 二叉平衡树 B树 红黑树 B+树 参考文档 顺序查找 给你一组数,最自然的效率最低的查找算法是顺序查找--从头到尾挨个挨个遍历查找,它的时间复杂度为O(n). 二分查找 而另 ...

随机推荐

  1. Codeforces-Anastasia and pebbles

    这是一道很有意思的(水)题. 地址戳:http://codeforces.com/problemset/problem/789/A 题目的大意呢,就是一个可爱的大姐姐的故事.说是啊,她每天都带着两个一 ...

  2. 【转载】EclEmma工具介绍

    https://wenku.baidu.com/view/1017567e5acfa1c7aa00cc5f.html https://www.ibm.com/developerworks/cn/rat ...

  3. JMeter 生成CSV文件中文变乱码的问题

    在通过BeanShell 生成CSV文件时,写入的中文字符默认情况会变成乱码. //默认情况生成的文件是asii编码.fileName = “c:\test.csv";fos = new F ...

  4. 【Mysql】【环境配置】Mac

    参看:http://www.cnblogs.com/chenmo-xpw/p/6102933.html     一.下载dmg包安装 1.下载MySQL dmg 包, 从官网 : http://www ...

  5. 下载安装tomcat和jdk,配置运行环境,与Intellij idea 2017关联

    第一篇博客,最近公司要用java和jsp开发新的项目,第一次使用Intellij idea 2017,有很多地方需要一步步配置,有些按照网上的教程很快就配置好了,有的还是琢磨了一会儿,在这里做一个记录 ...

  6. WebAPI使用Token进行验证

    1.需要用到的包  可以先敲代码   发现没有包在添加 2.在项目根目录下Web层添加“Startup”类   这个是Token的配置 3.在WebAPI层添加WebApiConfig类  也是Tok ...

  7. ArrayList list = new ArrayList()在这个泛型为Integer的ArrayList中存放一个String类型的对象

    java面试要点---ArrayList list = new ArrayList(); 在这个泛型为Integer的ArrayList中存放一个String类型的对象. ArrayList list ...

  8. Boostrap本地导入js文件

    我一般都是用CDN直接导入的,但是有时候需要自己添加一些功能进入,会用到本地导入.关于导入路径问题,做个笔记. 使用HBuilder,首先右键导入相应的js/cs文件 然后是常规——>文件系统 ...

  9. myeclipse新建maven项目

    右键 new--->project   ---->maven project 出现bank 右键点击bank---->maven4Myeclipse---->new maven ...

  10. 数据库:Mysql中“select ... for update”排他锁分析

    Mysql InnoDB 排他锁 用法: select … for update; 例如:select * from goods where id = 1 for update; 排他锁的申请前提:没 ...