二分查找边界控制

Posted joker D888

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分查找边界控制相关的知识,希望对你有一定的参考价值。

二分查找边界控制

前言

本文主要研究二分查找左右边界控制,不同的查找目的,边界控制会略有不同。以下都采用左闭右闭区间,仅在第一个示例中演示左闭右开区间。

二分的本质实际上是区间,即两段性,非此即彼。

查找某个特定值

// 左闭右闭
int binarySearch(int arr[],int n,int key)
	int low=0,high=n-1,mid;	// 左闭右闭,注意high=n-1
   	while(low<=high)
       mid=low+((high-low)>>1);	// 防溢出
	    if(key==arr[mid])
            return mid;
         else if(key<arr[mid])
            high=mid-1;
         else 
			low=mid+1;
        
	
    return -1;

// 左闭右开
int binarySearch(int arr[],int n,int key)
	int low=0,high=n,mid;	// 左闭右开,注意high=n
   	while(low<=high)
       mid=low+((high-low)>>1);	// 防溢出
	    if(key==arr[mid])
            return mid;
         else if(key<arr[mid])
            high=mid;
         else 
			low=mid+1;
        
	
    return -1;

查找第一个大于等于某个数的下标

// 终止前一步为: low=high,得mid = low,此时如果key <= a[mid],则high会改变,而low指向当前元素,即为满足要求的元素。如果key > a[mid],则low会改变,而low指向mid下一个元素。
int binarySearch(int arr[], int n, int key) 
	int low = 0, high = n - 1, mid;	// 左闭右闭
	while (low <= high) 
		mid = low + ((high - low) >> 1);	// 防溢出
		if (key <= arr[mid]) 	// <=
			high = mid - 1;
		 else 
			low = mid + 1;
		
	
	return low<=n?low:-1;

查找第一个大于某个数的下标

int binarySearch(int arr[], int n, int key) 
	int low = 0, high = n - 1, mid;	// 左闭右闭
	while (low <= high) 
		mid = low + ((high - low) >> 1);	// 防溢出
		if (key < arr[mid]) 	// <
			high = mid - 1;
		 else 
			low = mid + 1;
		
	
	return low<=n?low:-1;

二分模板

当我们将区间[l, r]划分成[l, mid]和[mid + 1, r]时,其更新操作是r = mid或者l = mid + 1;,计算mid时不需要加1。

int bsearch_1(int l, int r)

    while (l < r)
    
        int mid = l + r >> 1;
        if (check(mid)) r = mid;
        else l = mid + 1;
    
    return l;

当我们将区间[l, r]划分成[l, mid - 1]和[mid, r]时,其更新操作是r = mid - 1或者l = mid;,此时为了防止死循环,计算mid时需要加1。

int bsearch_2(int l, int r)

    while (l < r)
    
        int mid = l + r + 1 >> 1;
        if (check(mid)) l = mid;
        else r = mid - 1;
    
    return l;

这两个模板与上面的两个原理都一样,各有所爱即可。

扩展

(1) 查找数组中某个数的位置的最小下标

可以先查找数组中第一个大于等于某个数的位置,然后做一个判断,如果等于这个数直接返回下标,否则就返回-1

(2) 查找数组中某个数的位置的最大下标

可以先查找数组中第一个大于这个数的位置,然后将这个数和这个位置上的前一数进行比较,如果相等返回前一个位置,否则就返回-1。

(3) 查找数组中小于某个数的最大下标

可以先查找第一个大于等于这个数的下标,如果前一个位置有效,返回前一个位置,否则返回-1

(4) 查找数组中某个数的出现次数

首先用(1)求下界,然后用(2) 求上界,如果上界和下界都存在二者的差值+1就是出现的次数

以上是关于二分查找边界控制的主要内容,如果未能解决你的问题,请参考以下文章

19.scala的类型上下界

八二分查找

二分法(二分查找,二分答案)

STL二分算法

STL二分算法

STL二分算法