关于实施二进制搜索的快速问题:-)。这是我现在的功能,我还没有弄清楚为i传递正确数字的逻辑。但是,当我调试此函数时,我发现当value = values [i](匹配)时,发生了意外行为。
我的意图是返回true,从而触发匹配并退出该功能。实际行为导致返回true; 并跟随返回false; (错误地)。有谁知道如何确保回归真实;退出功能?还是提示我指导我的错误?非常感谢!
bool search(int value, int values[], int n){
int i = ((n - 1) / 2);
if(value == values[i])
{
return true;
}
else if(value < values[i])
{
n = i;
search(value, values, n);
}
else if(value > values[i])
{
n = (i * 1.5);
search(value, values, n);
}
return false;
}
答案 0 :(得分:4)
您遗漏了几个return
个关键字。
search(value, values, n);
应该是:
return search(value, values, n);
有两条这样的线。
如果没有return
个关键字,该函数将始终结束并返回false
。
更新,以回应OP的评论
您的函数没有任何检查以确保values
未被访问超出范围。我认为它永远不会尝试访问具有负索引的任何内容,但它有机会访问索引高于允许索引值的元素。我建议更改要使用的功能:
int search(int value, int values[], int start, int end)
{
if ( start >= end )
{
return 0;
}
int mid = (start + end)/2;
if(value < values[mid])
{
return search(value, values, start, mid);
}
else if(value > values[mid])
{
return search(value, values, mid+1, end);
}
else
{
return (value == values[mid]);
}
}
并在从函数外部调用时使用正确的start
和end
值进行调用。
int values[] = {1, 4, 6, 8};
bool found = search(2, values, 0, sizeof(values));
答案 1 :(得分:1)
让我评论说,可以用您的界面编写功能的有效版本。类似的东西:
bool search(int value, int values[], int n)
{
if (n == 0) // searching in an empty set?
return false;
int i = (n - 1) / 2;
if (value == values[i]) // the middle contains value?
return true;
else if (value < values[i]) // would be value to the left of i
return search(value, values, i);
else // so it would be to the right; no need of if (value > values[i])
return search(value, values + i + 1, n - i - 1);
}
此函数与您的签名具有相同的签名,通过元素数n
和数组指针的基数减少搜索范围。当在中心的左侧执行搜索时,元素的数量减少到i
,并且当向右执行搜索时,如果增加i + 1
并且元素的数量减少,则数组基地址i + 1
。
请注意,您的第三个if
不是必需的;如果达到,则谓词始终为真,因为value
不等于value[i]
,所以它更大。