编程新手。试图在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;
}
答案 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;
}