我在我的 C 二进制搜索代码中做错了什么?

What am I doing wrong in my C binary search code?

我正在研究二分搜索算法以准备我的编码面试,但是我的算法仅适用于最佳情况,即当搜索的数据位于中点时,O(1)。当我将值更改为更糟糕的情况(例如第一个位置)时,光标会卡住。

我知道二分查找有一个 O(log n) 更坏的情况,所以它应该不会花很长时间。我做错了吗?

#include <stdio.h>

int binary_search(int arr[], int left, int right, int data){
    // condition that runs only if true
    while(left <= right){
        int mid = (left + right) / 2;
        if(data == arr[mid]){
            return mid;
        }

        if(data > arr[mid]){
            binary_search(arr, mid+1, right, data);
        }

        binary_search(arr, left, mid-1, data);
    }
    return -1;
}

void main(){
    int arr[] = {1,2,3,4,5,6,7,8,9};
    int result = binary_search(arr, 0, (sizeof(arr)/sizeof(arr[0]) - 1), 2);
    (result == -1) ? printf("There was no record found\n") : printf("Your record was found at position %d\n", result+1);
}

您没有从函数中正确 return 触发无限递归。 在递归调用 binary_search(arr, mid+1, right, data); 的地方,您需要将 return 值传播回调用函数。

此外,与您的问题无关,但在 C void main() 中在技术上是不合法的,即使您可能不会收到任何明确的错误。 main() 应该 return 始终是一个 int。

#include <stdio.h>

int binary_search(int arr[], int left, int right, int data){
    // condition that runs only if true
    while(left <= right){
        int mid = (left + right) / 2;
        if(data == arr[mid]){
            return mid;
        }

        if(data > arr[mid]){
            return binary_search(arr, mid+1, right, data);
        }

        return binary_search(arr, left, mid-1, data);
    }
    return -1;
}

int main(void){
    int arr[] = {1,2,3,4,5,6,7,8,9};
    int result = binary_search(arr, 0, (sizeof(arr)/sizeof(arr[0]) - 1), 2);
    (result == -1) ? printf("There was no record found\n") : printf("Your record was found at position %d\n", result+1);

    return 0;
}

您的代码无法正常工作,因为如果在第一次迭代中 data 不等于 arr[mid],您的递归函数 return 就什么都不是。所以在这种情况下你将有一个无限递归。

但无论如何对于专业程序员来说,代码是非常非常薄弱的​​。

例如,您的函数可能不会为常量数组调用。 (是否还需要一个不同名称的函数?)

该函数应该只有三个参数

return_type binary_search( const int a[], size_t n, int data );

如果函数 return 是目标元素的索引,那么它的 return 类型应该是 size_t 因为通常 int 类型无法容纳表达式 sizeof( a ) / sizeof( *a ).

的值

如果函数只检查给定值是否存在于数组中,那么它应该 return 01 并且它的 return 类型应该是 int_Bool.

如果函数应该 return 目标值的位置,那么它应该 return 具有目标值的元素的第一个位置,与标准算法相同 std::lower_bound在 C++ 中。

复制标准 C 函数 bsearch 的相同缺点不是一个好主意,通常不会 return 具有目标值的第一个元素的位置。

您不得使用运算符 == 来比较值(尽管 C 中的比较函数使用此运算符),因为例如对于浮点数,您可能会得到错误的结果。您应该只使用运算符 <.

好吧,我们假设您的函数适用于元素类型为 int 且运算符 < 的数组。但是如果用户想使用自己的数组元素比较函数怎么办?

第二个问题,如果用户要使用元素类型为long long的数组或结构数组,他是否需要花时间再写一个二进制搜索函数?

我的建议:不要在面试中做任何作业。忽略那些试图操纵你和你的时间的公司。面试是平等伙伴的对话。如果您自己是一名合格的程序员,在简单的对话中很容易理解 "who is who"。 :)