我不会在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;
}
为什么while循环while(left<=right)
无法写入:
while(left<right)
?
这种变化会影响事情吗?
答案 0 :(得分:3)
举一个简单的
案例int a[1] = {5};
printf("%d\n", binarySearch(a, 1, 5));
使用while(low < high)
,代码打印-1(找不到 - 错误答案)。
使用while(low <= high)
,代码打印0(找到 - 正确答案)。
答案 1 :(得分:0)
这不是二进制搜索的完整摘要,但是为了解决这个问题,我将简短介绍一下。
这两个while循环条件的主要区别在于
1. low
(left
)和high
(right
)指针已相应更新。通过“相应地”,请参阅第3部分。
2.假设LOW
(LEFT
)和HIGH
(RIGHT
)的边界中没有重复项
3.假设目标存在于数组中
while(low <= high)
在[LOW
,HIGH
]范围内(包括两端)进行搜索。
相比之下,while(low < high)
会在[LOW
,HIGH
)范围(右/高端排他)中进行二进制搜索。对于在上/右范围/部分中对目标进行二进制搜索,它们总是会错过最后一个low
(left
)停在最末/右/上的检查。为了完全覆盖范围,通常建议根据最后一个low
(left
)指针做出另一个判断。
可能是任意的一般准则:
1.在处理目标肯定存在于数组中并且要搜索的数组不包含重复项的情况下,while(low <= high)
是首选
2.当处理数组中肯定没有目标并且数组可能包含重复项的情况时,建议使用while(low < high)
。
low
(left
)和high
(right
)指针“相应地”更新
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;
}
警告:可能引起混乱
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;
}
对于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;
}
本文不涉及二进制搜索的所有情况。有更复杂的要求,在掌握这些要求后,我将详细讨论。