二分搜索BinarySearch(代码模板)

本文提供二分查找算法的多种实现模板,包括寻找有序序列中第一个满足条件元素的位置、判断序列中是否存在满足条件的元素、upper_bound和lower_bound的实现。通过具体代码示例,帮助读者理解和掌握二分查找在不同场景下的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码来自 胡凡著的《算法笔记》一书,记录学习过程中的新的心得~
解决“寻找有序序列第一个满足某条件的元素的位置”问题的固定模板

1.二分区间为左闭右闭的[left,right],初值必须能够覆盖解的所有可能取值

int solve(int A[], int left, int right, int x) {
	int mid;
	while(left < right) {
		mid = (left + right) /2;
		if(条件成立) {  //条件成立,第一个满足条件的元素的位置<=mid
			right = mid;  //往左子区间 [ left , mid ] 查找
		} else {  //条件不成立,则第一个满足该条件的元素的位置>mid
			left = mid + 1;  //往右子区间 [ mid+1 , right ] 查找
		}
	}
	return left;  //返回夹出来的位置
}

2.二分区间为左开右闭的 ( left , right ],初值必须能够覆盖解的所有可能取值,并且left比最小取值小1

int solve(int A[], int left, int right, int x) {
	int mid;
	while(left + 1 < right) {
		mid = (left + right) /2;
		if(条件成立) {  //条件成立,第一个满足条件的元素的位置<=mid
			right = mid;  //往左子区间 [ left , mid ] 查找
		} else {  //条件不成立,则第一个满足该条件的元素的位置>mid
			left = mid;  //往右子区间 [ mid , right ] 查找
		}
	}
	return right; //返回夹出来的位置
}

3.查找序列中是否存在满足某条件的元素

#include <cstdio>

int binarySearch(int A[], int left, int right, int x) {
	int mid;
	while(left <= right) { //如果 left>right 就没办法形成闭区间了 
		mid = (left + right) / 2;  //取中点 
		if(A[mid] == x) return mid;  //找到 x, 返回下标 
		else if(A[mid] > x) {  // 中间的数大于 x 
			right = mid - 1;   // 往左子区间 [ left , mid-1 ] 查找 
		} else {  // 中间的数小于 x 
			left = mid + 1;  // 往右子区间 [ mid+1 , right] 查找 
		}
	}
	return -1; //查找失败,返回-1 
}

4.upper_bound
寻找第一个满足条件“值大于x”的元素的位置
A[ ] 为递增序列,x 为欲查询的数,函数返回第一个大于 x 的元素的位置
二分上下界为左闭右闭的 [ left , right ] ,传入的初值为 [ 0 , n ]

int upper_bound(int A[], int left, int right, int x) {
	int mid;
	while(left < right) { //对 [left,right] 来说,left=right 意味着找到唯一位置
		mid = ( left + right ) / 2;
		if(A[mid] > x) {
			right = mid;
		} else {
			left = mid + 1;
		}	
	}
	return left; //返回夹出来的位置,此时 left = right 
}

5.lower_bound
寻找第一个满足条件“值大于等于x”的元素的位置
与upper_bound的差别在于 A[mid] >= x

int upper_bound(int A[], int left, int right, int x) {
	int mid;
	while(left < right) { //对 [left,right] 来说,left=right 意味着找到唯一位置
		mid = ( left + right ) / 2;
		if(A[mid] >= x) {
			right = mid;
		} else {
			left = mid + 1;
		}	
	}
	return left; //返回夹出来的位置,此时 left = right 
}
### C++ 二分查找算法代码模板 以下是基于站内引用内容以及标准二分查找逻辑所整理的一个通用的 C++ 实现模板: ```cpp class Solution { public: int binarySearch(const vector<int>& nums, int target) { int left = 0; int right = nums.size() - 1; while (left <= right) { // 防止溢出,计算中间索引 int mid = left + (right - left) / 2; if (nums[mid] > target) { right = mid - 1; // 缩小右边界 } else if (nums[mid] < target) { left = mid + 1; // 扩展左边界 } else { return mid; // 成功找到目标值 } } return -1; // 如果未找到返回 -1 表示失败 } }; ``` 上述代码实现了经典的二分查找方法。它通过不断调整 `left` 和 `right` 边界来缩小搜索范围,直到定位到目标值或者确认不存在该值为止[^1]。 #### 关键点解析 - **初始化变量**:定义两个指针 `left` 和 `right` 来表示当前搜索区间的起始位置和结束位置。 - **循环条件**:当 `left <= right` 时继续执行循环操作,这意味着只要区间有效就持续搜索。 - **防止整数溢出**:采用 `int mid = left + (right - left) / 2;` 的方式代替简单的 `(left + right) / 2` ,从而避免可能发生的数值越界问题。 - **三种情况处理**: - 当前元素大于目标值,则更新右侧边界为 `mid - 1`; - 当前元素小于目标值,则更新左侧边界为 `mid + 1`; - 若两者相等则直接返回下标作为结果。 如果整个数组遍历完毕仍未发现匹配项,则最终返回 `-1` 值表明未能查找到指定的目标数据。 ### 注意事项 对于此版本而言,默认输入序列需满足升序排列的要求才能正常工作;另外需要注意的是,在实际应用过程中还应考虑更多特殊情况比如空集等情况下的异常捕获机制设计等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值