二分查找边界控制
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就是出现的次数
以上是关于二分查找边界控制的主要内容,如果未能解决你的问题,请参考以下文章