I am solving a simple binary search algorithm but I am not able to keep track of the last index in the question.
Although, I have tried and included a counter but in vain as it does not give me the expected output.
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");
}
Expected Output:-
Say my chosen number is 38. What are you going to do? Do a binary search:
Guess 50 (half of 0 to 100) → you’re too high.
Guess 25 (half of 0 to 50) → you’re too low.
Guess 37 (half of 25 to 50) → you’re too low.
Guess 43 (half of 37 to 50) → you’re too high.
Guess 40 (half of 37 to 43) → you’re too high.
Guess 38 (half of 37 to 40) → spot on!
Actual Output:-
Guess 50 (half of 0 to 100) -> you're too high.
Guess 25 (half of 0 to 50) -> you're too low.
Guess 37 (half of 25 to 50) -> you're too low.
Guess 43 (half of 37 to 50) -> you're too high.
//Here is my doubt
Guess 40 (half of 37 to 44) -> you're too high.
Guess 38 (half of 37 to 42) -> spot on!
The trick with efficient binary searches is that you check the very first and very last element in the array first.
Obviously, if the value you search for is outside, there is no need to do a binary search; and if either end matches, you have found it.
However, then it means that the boundaries for the binary search are exclusive. When you calculate the index for the next element to be probed, if it matches one of the boundaries, you know there is no match.
In pseudocode, this means we can write the binary search, assuming a sorted array with values in increasing values, and indexing starting at 0 as in C, as
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
When integer division is used, and iMin
and iMax
are nonnegative (positive or zero), i = (iMin + iMax)/2
rounds towards zero, and i == iMin
occurs first, so we do not need to explicitly check for i == iMax
. (That is, i == iMax
occurs in this case only when i == iMin
as well, so it is unnecessary to check.)
In the loop, when we update iMin
or iMax
, we have already examined array[iMin]
or array[iMax]
, respectively. iMin
refers to the index that has a smaller value than the one we are looking for, and iMax
to the index that has a larger value than the one we are looking for. So, we are essentially considering only array elements at indexes larger than iMin
but smaller than iMax
; excluding indexes iMin
and iMax
.