即使值已包含在已排序的数组中,C中的二进制搜索也会返回false

时间:2017-09-18 18:00:03

标签: c search

编程新手。试图在C中实现二进制搜索,但遗憾的是它无法正常工作。即使值在数组中,我的函数也总是返回false。编程新手。请帮忙。

功能需要以下输入: “value” - 在数组中找到的整数值。 “values” - 排序的数组。 “n” - 数组中的整数数。

bool search(int value, int values[], int n)
{
    // recursive implementation of binary search
    if (n % 2 == 0)
    {
        search_even(value, values, n);
    }
    else
    {
        search_odd(value, values, n);
    }
    return false;
}
bool search_even(int value, int values[], int n)
{
    // binary search
    if (n <= 0)
    {
        return false;
    }
    // check middle of array
    else if (value == values[n/2])
    {
        return true;
    }
    // search left half of sorted array
    else if (value < values[n/2])
    {
        int less_than_arr[n/2];
        for (int i = 0; i < n/2; i++)
        {
            less_than_arr[i] = values[i];
        }
        search(value, less_than_arr, n/2);
    }
    // search right half of sorted array
    else if (value > values[n/2])
    {
        int more_than_arr[(n/2) - 1];
        for (int i = 0; i < (n/2) - 1; i++)
        {
            more_than_arr[i] = values[i + 1 + n/2];
        }
        search(value, more_than_arr, n/2);
    }
    return false;
}

bool search_odd(int value, int values[], int n)
{
    // binary search
    if (n <= 0)
    {
        return false;
    }
    // check middle of array
    else if (value == values[n/2])
    {
        return true;
    }
    // search left half of sorted array
    else if (value < values[n/2])
    {
        int less_than_arr[n/2];
        for (int i = 0; i < n/2; i++)
        {
            less_than_arr[i] = values[i];
        }
        search(value, less_than_arr, n/2);
    }
    // search right half of sorted array
    else if (value > values[n/2])
    {
        int more_than_arr[n/2];
        for (int i = 0; i < n/2; i++)
        {
            more_than_arr[i] = values[i + 1 + n/2];
        }
        search(value, more_than_arr, n/2);
    }
    return false;
}

2 个答案:

答案 0 :(得分:2)

您(递归地)调用search函数但从不返回调用计算的值。看看:

bool search(int value, int values[], int n)
{
    // recursive implementation of binary search
    if (n % 2 == 0)
    {
        search_even(value, values, n);
    }
    else
    {
        search_odd(value, values, n);
    }
    return false;
}

此功能始终返回false。

您至少需要将search*(...)替换为return search*(...),以便在通话离开时确定的值会传回原始(第一)电话。

答案 1 :(得分:0)

Jean-Baptiste已经指出了你的功能中的明显错误,但还有更多问题:

您可以创建要搜索的子阵列的本地副本。这不是必需的,并且会使二进制搜索比线性搜索慢。

通常只有在想要修改数据时才需要复制数据,但保留原始状态。您的搜索功能仅检查数据。严格来说,您的论据int values[]应该const int values[]来反映这一事实。

在C中,必须将指针传递给第一个元素和数组的长度。数组衰减成指向第一个元素的指针,如下所示:

int val[4] = {2, 4, 7, 12};

search(3, val, 4);

已经这样做了。

但这是一个有用的习惯用法:如果你想传入从位置k开始的子数组,请使用:

search(3, val + k, 4 - k);

更一般地说,您可以传递数组切片[lo, hi),其中lo是从零开始的包含下限,hi是独占上限:

search(3, val + lo, hi - lo);

在被调用函数中,索引将为[0, hi - lo);原始数组偏移量丢失。

此外,如果您计算右侧数组的大小为原始大小减去原始大小之间的差异,则您不需要区分奇数n和偶数n这两种情况。左手阵列的大小加一:

mid == n / 2
left = [0, mid)
right = [mid + 1, n)

这样,您的递归二进制搜索功能将变为:

bool search(int value, const int values[], int n)
{
    if (n == 0) return false;

    if (value < values[n / 2]) {
        return search(value, values, n / 2);
    }

    if (value > values[n / 2]) {
        return search(value, values + n / 2 + 1, n - n / 2 - 1);
    }

    return true;
}