我正在用C ++实现二进制搜索算法,但算法没有返回正确的值。可以找到代码here。
template<class T>
int binary_search(T search_value, T search_array[]) {
int mid; /* The middle element of the remaining array to be searched. */
int min = 0; /* The first index of the array. */
/* This forumla gives us the size of the array. */
int max = sizeof(search_array)/sizeof(search_array[0]);
/* Continue searching until min >= max. */
while (min < max) {
/* Compute the value of mid using a formula that won't produce a number
* larger than the maximum allowed value of an integer. */
mid = (max-min)/2 + min;
/* Depending the whether search_value is larger or smaller than the
* value of whatever is at search_array[mid], set one of mid and max
* equal to mid. */
if (search_value > search_array[mid])
min = mid + 1;
else if (search_value < search_array[mid])
max = mid + 1;
else {
return mid;
}
}
return -1;
}
给定一个数组{0,1,3,5,7,9}并搜索3,该函数应该返回2,数组中的索引为3。我的函数返回-1,这意味着在数组中找不到3。问题出在哪里?
答案 0 :(得分:5)
int max = sizeof(search_array)/sizeof(search_array[0]);
这种方法不适合计算数组的大小,它只适用于创建数组的函数。
将数组的大小作为函数的参数传递,这是最简单的方法。
答案 1 :(得分:3)
这一行至少有一个问题:
int max = sizeof(search_array)/sizeof(search_array[0]);
数组不会通过函数传递,因此您的声明:
int binary_search(T search_value, T search_array[])
...与:
相同int binary_search(T search_value, T *search_array)
因此max
是指针的大小除以元素的大小,所以在最好的情况下它最多可以是6,但很可能是0或1。
我认为在C ++中你可以通过引用传递数组,并使用这样的声明形式知道它的大小:
template <size_t array_length>
void foo (const char (&data) [array_length])
{
// ...
}
答案 2 :(得分:2)
您的实施中存在错误:
else if (search_value < search_array[mid])
max = mid + 1;
应该是:
max = mid - 1;
答案 3 :(得分:2)
此行不符合您的预期:
int max = sizeof(search_array)/sizeof(search_array[0]);
因为数组在传递给函数时会自动衰减为指针,所以这实际上等于:
int max = sizeof(void*)/sizeof(search_array[0]);
这不是你想要的。使用存储大小的std::vector
或手动size_t array_length
参数。
答案 4 :(得分:2)
int max = sizeof(search_array)/sizeof(search_array[0]);
search_array
是指针而不是数组。
函数原型中T
类型数组的参数会自动调整为指向T
的指针。
答案 5 :(得分:2)
此行涉及:
int max = sizeof(search_array)/sizeof(search_array[0]);
sizeof(search_array)
将是指针的大小,4或8个字节,具体取决于平台。通常,我尽量避免在变量上使用sizeof
。它在类型上使用得更好。例如,在您的情况下sizeof(T)
。
答案 6 :(得分:1)
当索引从0开始时,你的最大值必须减少一个。