在数组中正确放置的二进制搜索

Posted

技术标签:

【中文标题】在数组中正确放置的二进制搜索【英文标题】:Binary Search for Correct Placement in Array 【发布时间】:2020-01-19 13:54:04 【问题描述】:

我正在尝试在数组上实现二进制搜索。我需要找到一个值应该放置的位置以保持数组中的顺序。我可以找到大量搜索现有值的帖子,但不一定是不存在值的正确位置。我需要它来处理偶数或奇数长度的数组。

$vals= [1,2,4,6,7,9,13];

$test_1 = 5; // should return 3
$test_2 = 10; // should return 6

function mySearch(array $array, $start, $end, $value)
    if($end<$start)return false;

    $mid = floor(($end + $start)/2);

    while($mid != $value)
        if($mid > $value)
            return mySearch($array, $start, $mid-1, $value);
        elseif($mid < $value)
            return mySearch($array, $mid+1, $end, $value);
        
    
    echo $mid;


【问题讨论】:

您是否曾经遇到过数组中已经存在值的情况?例如,您正在检查 10 并且 10 已经存在 @BrettGregson,如果这个函数出现,我们已经在数组中搜索了值的存在。所以它不应该存在。 【参考方案1】:

我相信,您可以通过验证您正在搜索的左侧和右侧的值来实现您想要做的事情,如下所示:

function mySearch(array $array, $start, $end, $value) 
    if ($end < $start) 
        return false;
    

    $index = floor(($end + $start)/2);
    $indexValue = $array[$index];

    // edge case when the value already exists on the array
    if ($indexValue == $value)  
        return $index;
    

    // test the value on the left side when value for the current index is greater
    // than the value being searched
    $previousIndex = $index - 1;
    if (
        $value < $indexValue 
        && (
            $previousIndex < 0 // edge case when there's no more values on the left side
            || $array[$previousIndex] <= $value
        )
    ) 
        return $index;
    

    // test the value on the right side when value for the current index is greater
    // than the value being searched
    if ($value > $indexValue) 
        $nextIndex = $index + 1;
        if ($nextIndex > $end || $array[$nextIndex] >= $value) 
            return $nextIndex;
         

        // edge case when the value would be appended to the array
        if ($nextIndex + 1 > $end) 
            return $nextIndex + 1;
        
    

    // normal binary search logic
    if ($indexValue < $value) 
        return mySearch($array, $index, $end, $value);
     else 
        return mySearch($array, $start, $index, $value);
    

我写了这个方法来验证它是否有效:

$testValues = range(0, 15);
$vals  = [1,2,4,6,7,9,13];

foreach ($testValues as $value) 
    if (in_array($value, $vals)) 
        continue;
    

    $index = mySearch($vals, 0, count($vals) - 1, $value);
    echo "For value: $value index: $index Array: " . printArray($vals, $index, $value);



function printArray(array $values, int $index, int $value) : string 
    $toPrint = [];
    $isAdded = false;

    foreach ($values as $i => $val) 
        if (!$isAdded && $i >= $index) 
            $toPrint[] = "($value)";
            $isAdded  = true;
        

        $toPrint[] = $val;
    

    if (!$isAdded) 
        $toPrint[] = "($value)";
    

    return "[" . implode(", ", $toPrint) . "]\n";

输出是:

For value: 0 index: 0 Array: [(0), 1, 2, 4, 6, 7, 9, 13]
For value: 3 index: 2 Array: [1, 2, (3), 4, 6, 7, 9, 13]
For value: 5 index: 3 Array: [1, 2, 4, (5), 6, 7, 9, 13]
For value: 8 index: 5 Array: [1, 2, 4, 6, 7, (8), 9, 13]
For value: 10 index: 6 Array: [1, 2, 4, 6, 7, 9, (10), 13]
For value: 11 index: 6 Array: [1, 2, 4, 6, 7, 9, (11), 13]
For value: 12 index: 6 Array: [1, 2, 4, 6, 7, 9, (12), 13]
For value: 14 index: 7 Array: [1, 2, 4, 6, 7, 9, 13, (14)]
For value: 15 index: 7 Array: [1, 2, 4, 6, 7, 9, 13, (15)]

【讨论】:

以上是关于在数组中正确放置的二进制搜索的主要内容,如果未能解决你的问题,请参考以下文章

二进制搜索以获取第一个整数的位置> =搜索的整数

许多排序数组中的二进制搜索

使用二进制搜索在数组中查找数字的位置

二进制/顺序搜索

二进制搜索算法:数组中每条记录的文本文件

在Python中的二进制搜索算法中查找数组的中间索引值