繁体   English   中英

如何在 C 中简化此工作二进制搜索代码?

[英]How can I simplify this working Binary Search code in C?

大家好,几周前开始用 C 编程,学习算法,只是想知道如何让我的代码更简单,它只是一个二进制搜索函数。 但唯一的事情是你必须保持论点相同,提前致谢。

bool search(int value, int values[], int n)
{
    int min = values[0];
    int max = values[n-1];
    int average = (min + max) / 2;

    if(average == value)
    {
        return true;
    }

    while (average > value) 
    {
        max = average - 1;
        average = (min + max) / 2;

    }

    while (average < value)
    {
        min = average + 1;
        average = (min + max) / 2;
    }

    if (max < min) 
    {
        return false;
    }
    if (average == value) {
         printf("%i\n", average);
        return true;
    }
    else
    {
        return false;
    }
}

在二分查找中有很多小事情你必须做对:处理 length=0 的情况,确保你测试的位置总是有效的,确保你没有溢出(即,`(low+high) /2' 不是最好的写法),确保新的测试位置总是与前一个不同,等等。

在做了一百万次之后,我写的每一个二分搜索现在都是这样完成的:

bool search(int[] array, int length, int valueToFind)
{
    int pos=0;
    int limit=length;
    while(pos<limit)
    {
        int testpos = pos+((limit-pos)>>1);

        if (array[testpos]<valueToFind)
            pos=testpos+1;
        else
            limit=testpos;
    }
    return (pos < length && array[pos]==valueToFind);
}

请注意,我们每次迭代只需要做一次比较,这比大多数可以做 2 的实现要快。而不是在循环内进行相等测试,我们可靠地找到要查找的元素所属的位置,每次只使用一次比较迭代,然后在最后测试以查看我们想要的元素是否在那里。

我们计算testpos的方式确保pos <= testpos < limit ,即使长度是最大可能的整数值,它也能工作。

这种形式还可以很容易地读出你想看到的不变量,而不必考虑像high<low这样奇怪的边界条件。 当您退出循环时, pos==limit这样您就不必担心使用错误的等等。

这个循环中的条件也很容易适应不同目的的二进制搜索,比如“找到插入 x 的位置,确保它在数组中已经存在的所有 x 之后”,“找到数组中的第一个x”,“找到数组中的最后一个x”等。

这不是二分查找的正确实现,所有条件都必须在一个循环中,例如: max 必须是 n-1 而不是 values[n-1] 和 min=0 而不是 values[0] 你也应该将 values[average] 与 value 进行比较,而不仅仅是平均变量。

 bool search(int value, int values[], int n){

    int min = 0;
    int max = n-1;
    int average ;

    while(max>=min){
        average = (min + max) / 2;
        if(values[average] == value)
        {
            return true;
        }

        if (values[average] > value) 
        {
            max = average - 1;
            average = (min + max) / 2;

        }

       if (values[average] < value)
        {
            min = average + 1;
            average = (min + max) / 2;
        }

    }

    return false;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM