c语言实现lower_bound和upper_bound

lower_bound(int A*,int l,int r,int val);
对于有序数组求职为val的元素插入位置,第一个出现该元素的位置.
分析:
等待插入的元素是val,有序数列是A[](此处按照升序排列),寻找的范围是[l,r];
如果查找区间只存在一个元素 l==r;时.
只需要判断val>A[l]时返回插入下标是l+1:
否则val<=A[l]返回的下表是l(因为要找的插入位置,小于或者相等都会插入到查找位置)
否则如果存在lr为不合法的情况,或者如果l>r时交换l和r)
可以取中点m=(l+r)/2;
比较A[m],与val的值的大小.
如果:
1.val>A[m];则如果A[]中存在val,那么一定是在右边,因此令l=m+1;
2.val 3.val=A[m];则如果A[]在m之前存在val,那么一定是在左边此时边界保留,或者不保留,令r=m;或者r=m-1(选择较好的m-1)
可以将二三合并为普遍情况r=m; (如果r=m-1没查到结果会出现到m处查到的情况,因此可以做这样的归并)
如果l 如果l (l+l)/2 + 1 (即为l+1) l'>l;

对于任意区间范围内l

一次算法描述可以是

int lower_bound(int *A,int L,int R,int val){
	int l=L,r=R;
	while(l
以一个例子说明
A[1]={1};
此时有l==r;
查找大值2;
由于2>A[(0+1)/2];
因此插入位置l+1,即为1;
查找相同值1;
插入位置是l,即为0.
查找小值0:
插入位置是0,即为0.


如果l A[5]={1,2,2,2,2};
此时查找2 (r=m)
第i次查找
i= 1  2  3  4  
l= 0  0  0  1
r= 4  2  1  1
m= 2  1  0  退出循环返回l,即为1.
如果零r=m-1;
l= 0  0  1
r= 4  1  1
m= 2  0  退出循环返回1
因此可以看出将情况A[m]=val,将r=m-1,效率更高O(log2n);

upper_bound思想同理

描述可以是

int upper_bound(int *A,int L,int R,int val){
	int l=L,r=R;
	while(l=A[m]){
			l=m+1;
		}else
			r=m-1;
	}
	return val>=A[r]?r+1:r;
}

int main(){
	int a[10]={1,2,2,2,2,2,2,4,5,6};
	printf("%d\n",lower_bound(a,0,9,2));
	printf("%d\n",upper_bound(a,0,9,2));
	return 0;
} 
执行结果


你可能感兴趣的:(c/c++常用算法)