在排序数组中,我需要找到第一个整数的位置> =给定的整数(如果数组中不存在这样的整数,则应返回-1)。二元搜索的以下修改是否正确解决问题?我使用了不少测试用例来验证功能,但仍想确认。
n =不。数组中的元素
ele =要搜索的整数
int binarySearch(int a[],int n,int ele)
{
int lower=0;
int upper=n-1;
int mid;
int pos=-1;
while(lower<=upper)
{
mid=(lower+upper)/2;
if (a[mid]==ele)
{
while(mid>=0 && a[mid]==ele)
mid--;
return mid+1;
}
else if(a[mid]<ele)
lower=mid+1;
else
{
pos=mid;
upper=mid-1;
}
}
return pos;
}
答案 0 :(得分:7)
你所写的不是二元搜索;在最坏的情况下,它是线性搜索。 (考虑当数组包含所有相同元素时会发生什么)。
信不信由你,正常的二进制搜索将完全符合您的要求(找到大于或等于目标的最小整数),只要它被正确编程。
我们可以在一些不变量的帮助下对其进行编程。
0 <= lo <= hi <= n
a[0..lo) < x
a[hi..n) >= x
其中x
是目标元素,而a[0..lo) <= x
表示半开放区间[0..lo)
中的所有元素都小于x
。
lo
和hi
是下限和上限,首先,它们将是0
和n
,这使得不变量中的两个范围最初都为空
现在算法:
int
binarySearch(int a[], int n, int x)
{
int lo = 0, hi = n;
while(lo < hi)
{
int mid = lo + (hi - lo)/2;
if(a[mid] < x) lo = mid + 1;
else hi = mid;
}
return hi;
}
因此,正文只是一个标准的二元搜索主体,包含mid
的非溢出计算。
决定lo
和hi
应分配哪个mid
也可以直接来自不变量:
a[mid] < x
那么a[mid]
应该在a[0..lo)
lo = mid + 1
范围内。a[mid] >= x
,则a[mid]
属于a[hi..n)
所以hi = mid
。 return语句也是不言自明的,因为给定不变量为真a[hi]
是a
中满足a[i] >= x
的最小元素。
接下来要看的最后一件事是while循环中的条件,具体来说,如果lo >= hi
考虑到不变量,那么这个循环将停止,只有lo = hi
才会发生。此时a[lo..hi)
为空,表示搜索空间已用完。
此实现的接口略微与您指定的不同,因为如果数组中没有这样的元素,那么它将范围a[hi..n)
视为空,这是真的何时hi = n
。这意味着它不是返回-1
,而是返回n
,这很容易检查,但如果你想让它返回-1
,只需将return语句替换为:
return hi < n ? hi : -1;