其实,有为青年在参与陌生商品价格竞猜节目的时候,是有技巧的。一贯场景可能都是这样的:

    • 拿着话筒的主持人

    13. 基础查找之二分查找 - 图1

    • 高端的不锈钢不粘锅

    13. 基础查找之二分查找 - 图2

    • 有为青年

    13. 基础查找之二分查找 - 图3

    一般情况下,游戏规则是有为青年在规定时间内猜测这个商品的价格,最后猜到的价格离这个商品的真实价格越近越好,越近奖励越丰厚,最后大奖就是把这个铁锅抱回家。

    所以,在经过女主持人一顿操作后,竞猜开始:有为青年:“500!”女主持人:“高了”有为青年:“250!”女主持人:“高了”有为青年:“125!”女主持人:“低了”有为青年:“ ( 125 + 250 ) / 2!”女主持人:“高了!”有为青年:“ ( 125 + ( 125 + 250 ) / 2 ) / 2!”女主持人:“中了!”

    作为普通青年,我们学习一下有为青年这种风骚的操作手法:也就是比较有名的二分查找。当然了,作为二分查找,是有一个前提的,那就是要查找的数据列表本身就是有序才行,不然,这个东西并没有什么卵用。

    道理是比较简单浅显易懂粗俗不堪,下面,我们通过手敲代码来感受一下:

    1. <?php
    2. $arr = [ 1,3,5,6,7,8,9,10,11,12,13,34,55,77,88,99,111,112,222,333 ];
    3. // 我们要从 arr 中找到 data
    4. function find( $arr, $data ){
    5. // 起始位置偏移量
    6. $begin_index = 0;
    7. // 末尾位置偏移量
    8. $end_index = count( $arr ) - 1;
    9. // 进入循环 终止条件是 当起始位置不再小于等于终止位置的时候
    10. while( $begin_index <= $end_index ){
    11. // 计算中间位置偏移量
    12. $mid_index = intval( ( $begin_index + $end_index ) / 2 );
    13. // 如果要找的值 比 中间位置的数值大
    14. if( $data > $arr[ $mid_index ] ){
    15. // 将起始位置偏移量更改为 中间位置+1
    16. $begin_index = $mid_index + 1;
    17. }
    18. // 如果要找的值 比 中间位置的数值小
    19. else if( $data < $arr[ $mid_index ] ){
    20. // 将末尾位置偏移量更改为 中间位置-1
    21. $end_index = $mid_index - 1;
    22. }
    23. // 如果等于了,也就是找到了
    24. else if( $data == $arr[ $mid_index ] ){
    25. return $mid_index;
    26. }
    27. }
    28. }
    29. echo find( $arr, 6 );
    30. echo PHP_EOL;
    31. echo find( $arr, 5 );
    32. echo PHP_EOL;

    上述代码,值得注意的有两处:

    • 11行,while循环的终止条件,这里务必注意,一定是有等号的
    • 13行,中间位置的取值。可能会有同学觉着这里会不会漏过一些数据,实际上不会的,因为11行的约束。13行这里你甚至改成ceil或者floor都没有问题的

    为什么突然这个时候冒出来一个二分查找呢?如果你仔细想想地话,上述查找过程就已经勾画出了一个二叉树,所以说,二分查找的时间复杂度是(logN)。因为二叉树我们前面好歹已经多多少少接触过一些了,所以引入二分查找就可以作为补充弥补一下了。