【问题标题】:How can you find an element using binary search on a recursive function C?如何在递归函数 C 上使用二进制搜索找到元素?
【发布时间】:2022-01-07 23:49:34
【问题描述】:

我编写了这个简码来在复杂度 O(log n) 的有序数组(从高到低)中查找元素 x 的位置。 narr 表示数组的边缘。 但是,它似乎无法正常工作。有什么建议吗?

int ex2_1(int *arr, int n, int key)
{
    if (n == 0)
        return -1;
    if (arr[n / 2] == key)
        return n / 2;
    if (arr[n / 2] > key)
        return ex2_1(arr + n / 2 + 1, n - n / 2 - 1, key);
    return ex2_1(arr, n / 2, key);
}

对于int arr[] = { 9, 7, 7, 5, 3, 3, 3, 1 };int n = 8int key = 3,当我应该得到5 时,我得到了4

【问题讨论】:

  • 请为您的参数使用更具描述性的名称,而不是隐晦命名的 n。目前尚不清楚n 代表什么。当你进行二分搜索时,你应该传递一个范围或界限,而不是一个标量。
  • “不起作用”从来都不是一个好的问题描述。请将完整代码显示为minimal reproducible example。即提供设置测试数据、调用函数并验证结果的main。还要给出确切的预期结果与实际结果。
  • “它似乎无法正常工作。” 我们知道,否则你不会在这里。它表现出什么行为,与您的预期有何不同。样本输入数据,编码为正确的minimal reproducible example,以及预期结果、实际结果以及迄今为止为推断问题所采取的步骤,对于格式良好的问题很重要。
  • 假设键对应于数组的最后一个元素。函数返回什么?在哪个递归深度?那个深度的论点是什么?

标签: c recursion binary-search


【解决方案1】:

您的递归函数返回错误结果的原因是您应该将递归调用的结果偏移从作为递归调用起点的数组开头的偏移量。仅当递归调用找到匹配项时才应执行此操作。

这是修改后的版本:

int ex2_1(const int *arr, int n, int key) {
    int m = n / 2;

    if (n == 0)
        return -1;
    if (arr[m] == key)
        return m;
    if (arr[m] > key) {
        int res = ex2_1(arr + m + 1, n - m - 1, key);
        return res < 0 ? res : res + m + 1;
    } else {
        return ex2_1(arr, m, key);
    }
}

【讨论】:

  • 这很接近但不太有效,因为您可以将n / 2 + 1 添加到-1
  • @n.1.8e9-where's-my-sharem.: 好点!答案已修改。
【解决方案2】:

在优化了 chqrlie 的代码后,我得到了这个,它运行良好:

int ex2_1(int* arr, int n, int key)
{
    if (n == 0) return -1;
    if (arr[n/2] == key) return n / 2;
    if (arr[n/2] > key)
    {
        int a = ex2_1(arr + n/2 + 1, n - n/2 - 1, key);
        if (a == -1) return -1;
        return n / 2 + 1 + a;
    }
    return ex2_1(arr, n/2, key);
}

【讨论】:

  • @chqrlie 我在你添加对 res 的检查之前发布了这个
猜你喜欢
  • 2021-05-10
  • 2014-11-27
  • 1970-01-01
  • 2021-04-28
  • 1970-01-01
  • 2016-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多