二分查找与其变体

二分查找针对的是一个有序的数据集合,时间复杂度为O(logn)

$data = [8,11,19,23,33,33,33,45,55,67,98];

普通的二分查找

function binarySearch(array $data,$find){
    $left  = 0;
    $right = count($data) - 1;
    while ($left <= $right) {
        $mid = $left + (($right-$left)>>1);
        if($find >$data[$mid]){
            $left  = $mid;
        }else if ($find < $data[$mid]){
            $right = $mid;
        }else{
            return $mid;
        }
    }
    return -1;
}

找到第一个=find的元素

function findFirstEqual(array $data,$find) {
    $length = count($data);
    $left = 0;
    $right = $length - 1;
    while($left <= $right) {
        $mid = $left + (($right-$left)>>1);
        if($data[$mid] > $find) {
            $right = $mid - 1;
        }else if($data[$mid] < $find) {
            $left = $mid + 1;
        }else {
            /**
             * 如果是第一个元素,或之前一个元素不等于我们要找的值
             * 我们就找到了第一个=find的element
             */
            if($mid==0 || $data[$mid-1]!=$find) {
                return $mid;
            }else {
                $right = $mid - 1;
            }
        }
    }

    return -1;
}

找到最后一个=find的元素

function findLastEqual(array $data,$find) {
    $length = count($data);
    $left = 0;
    $right = $length - 1;
    while($left <= $right) {
        $mid = $left + (($right-$left)>>1);
        if($data[$mid] > $find) {
            $right = $mid - 1;
        }else if($data[$mid] < $find) {
            $left = $mid + 1;
        }else {
            /**
             * 如果mid是最后一个元素的index
             * 或mid后一个元素!=我们要找的值
             * 则找到了最后一个=find的value
             */
            if($mid==$length-1 || $data[$mid+1]!=$find) {
                return $mid;
            }else {
                $left = $mid + 1;
            }
        }
    }

    return -1;
}

找到第一个大于等于find的元素

function findFirstGreaterEqual(array $data,$find) {
    $length = count($data);
    $left = 0;
    $right = $length - 1;
    while($left <= $right) {
        $mid = $left + (($right-$left)>>1);
        if($data[$mid] >= $find) {
            if ($mid == 0 || $data[$mid-1] < $find) {
                return $mid;
            }else {
                $right = $mid - 1;
            }
        }else  {
            $left  = $mid + 1;
        }
    }
    return -1;
}

找到最后一个小于等于find的元素

function findLastLessEqual(array $data,$find) {
    $length = count($data);
    $left = 0;
    $right = $length - 1;
    while($left <= $right) {
        $mid = $left + (($right-$left)>>1);
        if($data[$mid] <= $find) {
           if($mid==$length-1 || $data[$mid+1]> $find) {
               return $mid;
           }
           $left = $mid + 1;
        }else  {
            $right = $mid - 1;
        }
    }
    return -1;
}


  转载请注明: 南归 二分查找与其变体

 上一篇
单向链表操作 单向链表操作
PHP 操作单向链表class SingleLinkedListNode { /** * 节点中的数据域 * * @var null */ public $data; /**
2018-03-08
下一篇 
yield 生成器 读取超大文件 yield 生成器 读取超大文件
生成器函数的核心是yield关键字。它最简单的调用形式看起来像一个return申明,不同之处在于普通return会返回值并终止函数的执行,而yield会返回一个值给循环调用此生成器的代码并且只是暂停执行生成器函数。 读取超大文件functi
2018-02-01
  目录