1. 程式人生 > >修煉內功---資料結構與演算法16---二分法變形2

修煉內功---資料結構與演算法16---二分法變形2

在給定排序序列中查詢第一個大於等於給定值的元素

所不同的是判斷節點不一樣了,我們之前的需求都是查詢等於給定值

現在變成了大於等於給定值,所以我們要在 $nums[$mid] >= $num 這個判斷條件上做文章

思路還是和之前兩個變形版本類似

當 $mid 已經是最左邊的元素,或者 $mid 的前一個元素值小於給定查詢值,則 $mid 對應元素即為滿足條件的元素,否則繼續往前查詢

<?php

/**
 * 二分查詢變形版:查詢第一個大於等於給定值的元素(陣列中包含重複資料)
 */
function binary_search($nums, $num)
{
    if (count($nums) <= 1) return 0;

    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 ($nums[$mid] >= $num) {
        if ($mid == 0 || $nums[$mid - 1] < $num) {
            return $mid;
        } else {
            return binary_search_internal($nums, $num, $low, $mid - 1);
        }
    } elseif ($nums[$mid] < $num) {
        return binary_search_internal($nums, $num, $mid + 1, $high);
    }
}

$nums = [1, 2, 3, 4, 5, 6, 7, 8];
$index = binary_search($nums, 3);
print $index;

在給定序列中查詢最後一個小於等於給定值的元素

這次的判斷節點變成了 $nums[$mid] <= $num

其中 $num 是待查詢的元素值,當 $mid 已經是最後一個元素索引,或者 $mid 的後一個元素值大於 $num 則當前 $mid 對應元素就是要查詢的元素,否則要繼續往後查詢

<?php

/**
 * 二分查詢變形版:查詢最後一個小於等於給定值的元素(陣列中包含重複資料)
 */
function binary_search($nums, $num)
{
    if (count($nums) <= 1) return 0;

    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 ($nums[$mid] <= $num) {
        if ($mid == count($nums) - 1 || $nums[$mid + 1] > $num) {
            return $mid;
        } else {
            return binary_search_internal($nums, $num, $mid + 1, $high);
        }
    } elseif ($nums[$mid] > $num) {
        return binary_search_internal($nums, $num, $low, $mid - 1);
    }
}

$nums = [1, 2, 3, 4, 5, 6, 7, 8];
$index = binary_search($nums, 3);
print $index;