There's something that I don't get with the binary search code on C.
int binarySearch(int a[], int n, int x)
{
int low=0, mid, high=n-1;
while(low <= high)
{
mid = (low + high) / 2;
if (x < a[mid])
high = mid - 1;
else if (x > a[mid])
low = mid + 1;
else
return mid;
}
return -1;
}
Why does the while loop while(left<=right)
can't be written:
while(left<right)
?
Will this change effect things?
Take a simple case of
int a[1] = {5};
printf("%d\n", binarySearch(a, 1, 5));
With while(low < high)
, code prints -1 (did not find - wrong answer).
With while(low <= high)
, code prints 0 (found - right answer).
This is not a complete summary of the binary search, but I will put it in short to solve this question.
The key difference for these two while loop conditions, given
1. that the low
(left
) and high
(right
) pointers are updated accordingly. By "accordingly", please see part 3.
2. given that there is no duplicate in the boundary of LOW
(LEFT
) and HIGH
(RIGHT
)
3. given that the target exists in the array while(low <= high)
does the search in the range of [LOW
, HIGH
], both ends inclusive.
In comparison while(low < high)
does the binary search in the range [LOW
, HIGH
), right/high end exclusive. For binary searches of the target in the upper/right range/part, they always miss checks at the very end/right/high, where the last low
(left
) stops. To make the range fully covered, one is usually recommended to make another judgement, based on the last low
(left
) pointer.
General guidelines that might be arbitrary:
1. when dealing with situations where the target surely exists in the array, and the array for search does not contain duplicates, while(low <= high)
is preferred
2. when dealing with situations where target does not surely exist in the array, and the array might contain duplicates, while(low < high)
is recommended.
low
(left
) and high
(right
) pointers updated "accordingly"
public int binarySearch(int[] nums, int target){
int left = 0, right = nums.length - 1;
// please pay attention to the initial condition of right(ptr)
while(left <= right){
// to floor the mid
int mid = left + (right - left) / 2;
// to check whether the middle element is equal to the target in every iteration
if(nums[mid] == target) return mid;
else if(target > nums[mid]) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
public int binarySearch(int[] nums, int target){
// please pay attention to the initial condition or the right(ptr)
int left = 0, right = nums.length;
while(left < right){
int mid = left + (right - left) / 2;
// please pay twice attention to the equality case
if(target > nums[mid]) {
left = mid + 1;
} else {
right = mid;
}
}
return left;
}
Warning: Confusions might be caused
for the type of while(low <= high)
:
public int binarySearchWithFlooringMid(int[] nums, int target){
// please pay attention to the initial condition of right(ptr)
int left = 0, right = nums.length - 1;
while(left <= right){
// to floor the mid
int mid = left + (right - left) / 2;
// to check whether the middle element is equal to the target in every iteration
if(nums[mid] == target) return mid;
else if(target > nums[mid]) {
left = mid + 1;
} else {
right = mid;
}
}
return -1;
}
public int binarySearchWithCeilingMid(int[] nums, int target){
int left = 0, right = nums.length - 1;
while(left <= right){
// to ceil the mid
int mid = left + (right - left + 1) / 2;
// to check whether the middle element is equal to the target in every iteration
if(nums[mid] == target) return mid;
else if(target > nums[mid]) {
left = mid;
} else {
right = mid - 1;
}
}
return -1;
}
For the type of while(low < high)
public int binarySearchLeftmost(int[] nums, int target){
int left = 0, right = nums.length;
while(left < right){
int mid = left + (right - left) / 2;
// please pay twice attention to the equality case
if(target > nums[mid]) {
left = mid + 1;
} else {
right = mid;
}
}
return left;
}
public int binarySearchRightmost(int[] nums, int target){
int left = 0, right = nums.length;
while(left < right){
int mid = left + (right - left) / 2;
// please pay twice attention to the equality case
if(target < nums[mid]) {
right = mid;
} else {
left = mid + 1;
}
}
return right - 1;
}
This post does NOT cover all the cases in terms of binary searches. There are much more sophisticated requirements, which I will talk about in more details after mastering them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With