我正在解决一种简单的二进制搜索算法,但无法跟踪问题中的最后一个索引。
尽管,我尝试并包括了一个计数器,但由于没有给我期望的输出而徒劳,
void binarySearch(int Arr[], int Size, int Search)
{
int Flag=0, Counter=1, First=0, Last=Size-1, Mid;
while(First<=Last)
{
Mid=(First+Last)/2;
printf("\nGuess %d (half of %d to %d) -> ", Arr[Mid], First,
(Last+Counter));
if(Arr[Mid]==Search)
{
printf("spot on!");
Flag=1;
break;
}
else if(Arr[Mid]<Search)
{
printf("you're too low.");
First=Mid+1;
}
else
{
++Counter;
printf("you're too high.");
Last=Mid-1;
}
}
if(Flag==0)
printf("\nElement Not Found!!");
printf("\n");
}
预期输出:-
说我选择的电话号码是38。您打算做什么?进行二进制搜索:
猜50(从0到100的一半)→您太高了。
猜25(0至50的一半)→你太低了。
猜猜37(25至50的一半)→你太低了。
猜猜43(37至50的一半)→你太高了。
猜40(从37到43的一半)→你太高了。
猜猜38(37至40的一半)→当场!
实际输出:-
猜50(0至100的一半)->你太高了。
猜25(0至50的一半)->你太低了。
猜猜37(25至50的一半)->你太低了。
猜猜43(37至50的一半)->你太高了。
//这是我的疑问
猜40(从37到44的一半)->你太高了。
猜猜38(37至42的一半)->当场!
答案 0 :(得分:3)
有效的二进制搜索的诀窍是您首先检查数组中的第一个和最后一个元素。
很显然,如果您搜索的值在外部,则无需执行二进制搜索;如果两端都匹配,您就找到了。
但是,这意味着二进制搜索的边界是排他性的。在计算下一个要探查的元素的索引时,如果它与边界之一匹配,则说明没有匹配项。
在伪代码中,这意味着我们可以编写二进制搜索,假设排序的数组中值的值递增,并像C中一样从0开始索引,如下所示:
Function BinarySearch(array[], length, value):
If (length < 1):
# Empty array.
Return NotFound
End If
If (value < array[0]):
# Value is smaller than those in the array.
Return NotFound
Else If (value == array[0]):
Return Found at index 0
End If
If (value > array[length - 1]):
# Value is greater than those in the array.
Return NotFound
Else If (value == array[length - 1]):
Return Found at index length - 1
End If
Let iMin = 0
Let iMax = length - 1
Loop:
Let i = (iMin + iMax) / 2 # Integer division, rounds towards zero
If (i == iMin):
Return NotFound
End If
If (array[i] < value):
iMin = i
Else If (array[i] > value):
iMax = i
Else:
Return Found at index i
End If
End Loop
End Function
使用整数除法,并且iMin
和iMax
为非负数(正数或零)时,i = (iMin + iMax)/2
会四舍五入到零,而i == iMin
首先出现,所以我们这样做无需显式检查i == iMax
。 (也就是说,i == iMax
在这种情况下也仅在i == iMin
时出现,因此没有必要进行检查。)
在循环中,当我们更新iMin
或iMax
时,我们已经分别检查过array[iMin]
或array[iMax]
。 iMin
是指索引值比我们要寻找的索引小的索引,iMax
是指索引值比我们要寻找的索引的索引更大。因此,我们基本上只考虑索引大于 iMin
但小于 iMax
的数组元素;排除索引iMin
和iMax
。