二进制搜索不变以查找元素的首次出现
invariant of binary search for finding first occurrence of an element
我在定义找到二进制搜索的第一个元素的不变性方面存在问题。(我有一个排序的数组a,我想找到等于某个数字q的第一个元素,如果它不存在,则返回-1(
(首先,我为自己设置了这个不变的。
我的不变
"始终是a [l]< = q,还有a [r]> q" ==>"始终l< = ind and> ind and> ind'。
到我的不变,我写了此代码:
int l=0,r=n;
while(l<r){
int mid=(r+l)/2;
if(a[mid]==q){
r=mid+1;
}
else{
if(a[mid]>q){
r=mid;
}else if(a[mid]<q) l=mid+1;
}
}
return l;
但是有一个问题是if(a[mid]==q)
然后我必须选择一个不会违反我不变的r
。
如果我选择mid-1
,我会违反它,因为a[r]
将为&lt; = q
。
我必须遍历索引,直到找到 a[i]>q
的索引i,然后将r
设置为该索引。(r = i(==>,但是如果我这样做,那不是 O(log n)
我已经看到了一些实现lower_bound
的代码,该if(a[mid]==q)
将r
设置为mid
,但我认为它们违反了它们不变性,但它们是正确的,但它们是正确的并返回了正确的值。
喜欢此代码:
1- int l = 0;
2- int r = n; // Not n - 1
3- while (l < r) {
4- int mid = (l + r) / 2;
5- if (q <= a[mid]) {
6- r = mid;
7- } else {
8- l = mid + 1;
9- }
10- }
11- return l;
首先,不变性就像我的不变(i
在[l,r)
的范围内(,但在第5行中考虑if(q==a[mid])
,然后显然是因为它违反了([l,r]
,因为CC_16是相等的,并且可以是第一次出现(。
我是对的,还是我没有不变的正确理解概念?
假设我们有一个序列
..., <q, <q, <q, q, q, ..., q, q, >q, >q, >q, ...
^ (*)
其中<q
(>q
(代表任何元素< q
(> q
(。我们想找到点(*(。
我们有两个指针left < right
。我们如何使用它们来区分这一点?答案很简单:left
应该指向最后一个<q
元素,right
应指向第一个q
元素:
..., <q, <q, <q, q, q, ..., q, q, >q, >q, >q, ...
^ right
^ left
不变的是:*left < q
和*right >= q
。
您建议的不变式*left <= q
和*right > q
对应于该顺序中的最后一个元素:
..., <q, <q, <q, q, q, ..., q, q, >q, >q, >q, ...
^ right
^ left
一些可能有用的引用:
col.4:编写正确的程序&ndash;J.Bentley。编程珍珠。Addison-Wesley,2 nd Ed。,1999。书网站
J.Bentley。编程珍珠:编写正确的程序。ACM 26 ,1040(1983(的通信。全文
二进制搜索&ndash;DR.DOBB的日记第一部分,第二部分,第三部分,第四部分,第五部分第六部分,第七部分,第七部分,第IX部分,X部分
- 使用堆查找第K个最大元素的时间复杂性
- 查找矩阵C++中每一列和每一行的最小和最大元素
- C++如何在向量中查找最常见的元素
- 查找两个排序向量中共有的元素
- 在对向量中查找元素的索引
- 查找数组中第一个最小值和最后一个最大值元素之间的算术平均值
- 查找矩阵中单元格的相邻元素
- 为什么使用数组元素查找最大数字的程序不起作用?
- 查找第一个数组中不存在的元素
- 查找最小的下一个更大的元素
- 在最小堆中查找最大元素
- 在向量中查找大于 0(或通常为 k)的最小元素的最佳方法是什么?
- set::find 查找不存在的元素
- 在集合中查找使用结构C++的元素
- 从斐波那契序列 c++ 中的数组中查找正确的元素时出错
- 用于查找数组中最大元素的出现次数的代码,给出分段错误
- 查找数组中指示性较大但数组中值较小的元素
- C++结构集无法按元素查找/擦除
- 如何在OpenCV中使用Matlab的512元素查找表数组?
- 使用数组的元素查找总和'k'