C语言 请帮助我理解二进制搜索函数中的while条件

6fe3ivhb  于 2022-12-17  发布在  其他
关注(0)|答案(3)|浏览(106)

我正在用C语言学习数组排序和while循环,下面是我用来学习这个的书中的一些代码:

//function to perform binary search of an array
size_t binarySearch(const int b[], int searchKey, size_t low, size_t high)
{
    //loop until low index is greater than high index
    while (low <= high) {
        
        //determine middle element of subarray being searched
        size_t middle = (low + high) / 2;

        //display subarray used in this iteration
        printRow(b, low, middle, high);

        // if searchKey matched middle element, return middle
        if (searchKey == b[middle]) {
             return middle;
        }

        // if searchKey is less than middle element, set new high
        else if (searchKey < b[middle]) {
           high = middle - 1; //search low end of array
        }

        else {
           low = middle + 1; //search high end of the array
        }
     }//end while

     return -1; //searchKey not found
}

问题是,我不知道初始while条件是如何工作的:while (low <= high)。我的意思是,似乎low永远不会大于high。谁能告诉我,在什么情况下,low会大于high,从而终止循环?
我试着写下并想象算法是如何工作的,但我无法理解它。

aij0ehis

aij0ehis1#

在这些条件下,low值大于high

**当一个元素不在列表中并且要查找的元素大于中间的元素时:**列表中只有一个元素,因此low = middle + 1将执行,并且low的结果值大于
在函数调用中,我们传递的high大于low

binarySearch(arr, search_value, 4, 3)

尝试这些输入

输入

array = {2, 3, 4, 10, 40}
to_search = 11

输出(低、高)

0, 4
3, 4
4, 4
4, 3  <--- low > high
hkmswyz6

hkmswyz62#

好吧,不要把这句话当作日常谈话中的事情,当然,通常不会讨论5比8大的可能性。
但是在代码、循环和条件中,情况就不同了,因为代码是动态的。如果你按照代码,在许多条件中,你会看到low = middle + 1;的情况(这是最后一个条件)。在“相反”的频谱中,你会看到它上面的条件high = middle - 1;。当然,还有一个控制中间的条件:middle = (low + high) / 2; .
在这种情况下,低有机会(假设你达到它的条件)增加,高有机会(再次假设你达到它的条件)减少。
回到5和8开头的随机示例,这意味着第一个数字最终可能从7上升到7,8可能下降到4。当然,在我们的代码中,您需要遵循实际流程,查看值以及它们如何以及何时达到这些条件。
但底线是,low和high从来都不是静态的,这种情况很少见,因为你会发现大多数循环只修改第一个变量(在我们的例子中是low),但有一种循环模式是这样的:你从一个值或一个条件开始,然后你在代码中前进,直到你打破那个条件。
小警告:因为控制流是人为的,如果不注意,它们可能以无限循环结束(意味着停止条件从未被触发)。这意味着程序将进入循环,基本上“静止不动”,但仍然会消耗CPU的能力(并且,取决于它在循环中做什么,甚至消耗内存,直到机器耗尽内存)。
在一些循环中,您将看到以下内容作为预防措施:

int i = 0;
while (some condition)
{
    if (i++ > some number)
        break;

    ... some control flow code
}

这是一个故障保护停止。变量在每个循环中递增,直到程序员认为足够安全的数字,然后循环就存在了。break是你退出循环的方式。当然,这只是一个故障保护,就像我说的,通常你需要确保循环中的代码被正确处理,没有无限循环发生的机会。

0yycz8jy

0yycz8jy3#

让我们假设searchKey不在你的数组中,以便于解释。

  • b{ 1, 2, 3 }
  • searchKey4
  • low0
  • high2

一开始low小于high,所以我们进入while循环。middle等于(0 + 2) / 2,也就是1。在我们的特殊情况下,我们命中else语句,这意味着我们将low设置为middle + 1,也就是2。这意味着low现在等于high,所以循环继续,这次middle(2 + 2) / 2,也就是2。我们再次执行else语句,将low设置为3,使low大于high,然后结束循环
如果searchKey-1,那么我们会将high设置为middle - 1,也就是0,这意味着high现在等于low,在下一次循环迭代中,我们会再次将high设置为-1,从而结束循环

相关问题