我正在为二进制搜索算法编写代码。
代码:
#include "cs50.h"
int main(void) {
int n = GetInt();
int value = GetInt();
int values[n];
for (int i = 0; i < n; i++) {
printf("Put in number %i ", i + 1);
values[i] = GetInt();
}
int mid = (n - 1) / 2;
int en = 0;
int ex = n - 1;
for (int i = 0, xt = i + 1; i < xt; i++) {
if (value > values[mid]) {
en = mid;
mid = (en + ex) / 2;
}
else if (value < values[mid]) {
ex = mid;
mid = (en + ex) / 2;
}
else if (value == values[mid]) {
printf("found");
break;
} else {
printf("not found");
break;
}
}
}
但它只有在找到的值位于中间某处时才有效。
在以下时间失败:
我真的无法弄清楚这个错误。
答案 0 :(得分:4)
你需要在二进制搜索中找到一些小东西:处理长度= 0的情况,确保你测试的位置始终有效,确保你没有溢出(即,` (低+高)/ 2&#39;不是最好的写方式),确保新的测试位置总是与前一个不同,等等。
在完成了一百万次之后,我写的每个二进制搜索现在都是这样完成的:
bool search(int array[], int length, int valueToFind)
{
int pos = 0;
int limit = length;
while(pos < limit)
{
int testpos = pos + ((limit - pos) >> 1);
if (array[testpos] < valueToFind)
pos = testpos + 1;
else
limit = testpos;
}
return (pos < length && array[pos] == valueToFind);
}
请注意,我们每次迭代只需要进行一次比较,这比其他答案中的搜索要快。我们不是在循环中进行相等测试,而是可靠地找到要查找的元素所在的位置,每次迭代只使用一次比较,然后在结束测试时查看我们想要的元素是否存在。
我们计算testpos
的方式可以确保pos <= testpos < limit
,即使长度是最大可能的整数值,它也能正常工作。
这种形式还可以很容易地读出你想要看到的不变量,而不必考虑像high<low
这样奇怪的边界条件。当你走出循环时,pos==limit
所以你不必担心使用错误的等等。
这个循环中的条件也很容易适应不同目的的二进制搜索,例如&#34;找到插入x的位置,确保它在已经在数组中的所有x之后#34;,&#34 ;在数组&#34;中找到第一个 x,&#34;在数组&#34;等中找到 last x。
答案 1 :(得分:2)
在我看来,for循环只会运行一次
for(int i = 0, xt = i + 1; i < xt; i++) {}
另外,为了使二进制搜索算法起作用,需要对整数列表进行排序。我不确定GetInt()究竟做了什么,但如果它返回一个随机值,那么也会导致搜索失败。
答案 2 :(得分:2)
正如其他人所说,你在for
循环中遇到了错误的条件。
还有一个问题是
if (value > values[mid])
{
en = mid;
mid = (en+ex)/2;
}
此时(value > values[mid])
您将en
分配到mid+1
,而mid
必须分配,因为您必须在 {之后搜索元素{1}}
类似地,如果(value < values[mid])
,ex
必须分配mid-1
,因为您必须搜索元素直到索引 {{1 小于 1
二进制搜索的更好实现如下:
注意:我分别使用
mid
和low
代替high
和en
ex
进行上述更改后,代码将为:
int mid; //no need to initialize as mid is initialized at the start of each iteration
int low = 0; //instead of en
int high = n-1; //instead of ex
while( low <= high )
{
mid = low + ((high - low) / 2);; //updating mid value
if (value > values[mid])
{
low = mid+1; //updating low
}
else if (value < values[mid])
{
high = mid-1; //updating high
}
else // if (value == values[mid])
{
printf("found"); //if found print 'found'
break;
}
}
if(low>high)
printf("not found\n");
示例输入:
#include "cs50.h"
#include <stdio.h>
int main(void)
{
int n = GetInt();
int value = GetInt();
if (n <= 0)
{
//handle the error or exit
}
int values[n];
for (int i=0;i<n;i++)
{
printf("Put in number %i \n",i+1);
values[i]=GetInt();
}
int mid;
int low = 0;
int high = n-1;
while( low <= high )
{
mid = low + ((high - low) / 2);
if (value > values[mid])
{
low = mid+1;
}
else if (value < values[mid])
{
high = mid-1;
}
else
{
printf("found");
break;
}
}
if(low>high)
printf("not found\n");
}
示例输出:
5 //n
5 //value
1 2 3 4 5 //array elements
进一步阅读,请阅读:click