标签:二分 边界 静态 int 算法 查找 目标值 target
1.二分查找的前提:
二分查找属于静态查找表系列算法的有序表查找算法,意思就是二分查找应该使用在有序数列中,数列必须是升序或者降序排列。
2.主流二分查找应用场景:
2.1 二分查找目标值
int find(int *ar, int l, int r, int target) {
while(l <= r) {
int mid = (l + r) / 2;
if(ar[mid] == target)
return mid;
else if(ar[mid] > target)
r = mid - 1;
else
l = mid + 1;
}
return -1;
}
思路:
二分查找的思路大致叙述为是根据中间值的状况,每次把查找区间缩小一半。当查找区间缩小为左边界等于右边界时到达查找最终状态,下一个状态退出查找。
2.2 二分查找第一个比目标值大的值
int find(int *ar, int length, int target) {
int l = 0, r = length - 1, mid;
while(l <= r) {
mid = (l + r) / 2;
if(ar[mid] <= target)
l = mid + 1;
else
r = mid - 1;
}
return l;
}
思路:
基本思路:
二分查找第一个比目标值大的值的思路大致叙述为是根据中间值的状况,每次把查找区间缩小一半。当查找区间缩小为左边界等于右边界时到达查找最终状态,下一个状态退出查找。但是由此无法确定状态退出时到底是左边界为预期结果还是右边界是预期结果。
返回值是左边界还是右边界的确认:
由于二分查找应用在有序数列中,因此除了最终状态,其余所有状态下都是左边界的值小于右边界的值,且目标值介于两者之间(假设在一个升序顺序的数列中)。因此倒数第二个状态一定是区间长度为2,左边界小于右边界,由此推导出最终状态一定是右边界左移一位,此时左边界等于右边界且当前值小于目标值。再下一个状态时,退出查找,一定是左边界右移一位,此时左边界对应的值就是第一个比目标值大的值。
数列中存在多个目标值的解决方案:
假如数列中存在一些数和目标值相等,此时要考虑在这种
ar[mid] = target
情况下到底要让左边界右移还是让右边界左移。在二分查找中,除了最后一次区间,其余区间都应该满足目标值介于左边界对应值和右边界对应值之间。如果在ar[mid] = target
情况下让右边界左移,那么将不能满足二分查找边界要求。因此应该让左边界右移,就是上述代码的ar[mid] <= target
对应的处理方案。
测试:
int ar[12] = {1, 2, 3, 4, 5, 6, 6, 6, 7, 8, 9, 10}, target = 6;
cout << find(ar, 0, 11, 6); // 8
2.3 二分查找第一个比目标值小的值
int find(int *ar, int l, int r, int target) {
while(l <= r) {
int mid = (l + r) / 2;
if(ar[mid] <= target)
r = mid - 1;
else
l = mid + 1;
}
return l;
}
思路:
思路同上
3.归纳二分查找的要求
- 二分查找适用于升序或降序的有序序列。
- 二分查找基本思路是每次查找将查找区间缩小一半,最终状态时左边界等于右边界,下一个状态停止查找。
- 二分查找在查找过程中应该始终保持目标值介于左边界对应值和右边界对应值之间。
- 二分查找目标值时返回中间值mid,二分查找第一个比目标值大/小的值时返回左边界l。
标签:二分,边界,静态,int,算法,查找,目标值,target 来源: https://blog.csdn.net/qq_37464878/article/details/123058474
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。