二分查找(Binary Search)是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。
要想要了解二分查找的算法,不妨先来玩一个游戏帮助你理解过程:
现在,我从0-9抽取一个数字:6(假设你不知道它,这里告诉你是为了帮你理解),你现在需要猜他,你每次猜错我都会告诉你你的数字大了还是小了,你会怎么猜?(抱歉,我太懒,1-10中10我图片中搞成了0,我不想重新搞了!评论区喷的轻一点吧!)
有人说:“很简单啊,1-10全都试一遍,总能猜对!”
是啊,如果1-99999,你还敢一个一个猜吗?
那么,让我们来看一下二分查找怎么猜
首先,10÷2=5,5是“中点”,所以我们猜测5。
好,5小了。
所以可能的范围缩小到了6-10
6 - 10中的“中点”是8,我们猜8,8大了。可能的范围只有6,7了,然后猜6,6对了就是6,6不对就是7.
这个游戏玩明白了吗?
玩明白了就代表你已经学会一半的二分查找了。
剩下的一半,就是代码实现。
实现逻辑就是定义俩变量left和righ,表示可能范围的左边界和右边界。‘
然后用right-left+1求出可能的有几个,求出中间的那个中点是第几个。
然后求中点的值:用left+中点是第几个-1
然后你应该会了吧
好了,不啰嗦了,上代码
#include <iostream>
#include <vector>
using namespace std;
// 二分查找函数
int binarySearch(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) {
return mid;
}
// 如果中间元素大于目标值,在左半部分搜索
else if (nums[mid] > target) {
right = mid - 1;
}
// 如果中间元素小于目标值,在右半部分搜索
else {
left = mid + 1;
}
}
// 如果没有找到目标值,返回-1
return -1;
}
int main() {
vector<int> nums = {1, 3, 5, 7, 9};
int target = 5;
int result = binarySearch(nums, target);
if (result != -1) {
cout << "Element found at index: " << result << endl;
} else {
cout << "Element not found in array" << endl;
}
return 0;
}
代码解释:
-
定义了一个
binarySearch
函数,该函数接受一个整数数组nums
和一个目标值target
作为参数。 -
初始化左边界
left
为 0,右边界right
为数组nums
的最后一个元素的索引。 -
使用
while
循环进行搜索,直到左边界大于右边界时结束。 -
在循环内部,计算中间索引
mid
。注意这里使用了(right - left) / 2
而不是(right + left) / 2
,这是为了防止在left
和right
都很大时发生整数溢出。 -
检查中间元素
nums[mid]
是否等于目标值target
。如果是,则返回mid
。 -
如果
nums[mid]
大于target
,则将搜索范围缩小到左半部分,更新右边界right
为mid - 1
。 -
如果
nums[mid]
小于target
,则将搜索范围缩小到右半部分,更新左边界left
为mid + 1
。 -
如果在循环结束时仍未找到目标值,则返回 -1。
-
在
main
函数中,创建了一个有序数组nums
和一个目标值target
,然后调用binarySearch
函数进行搜索,并打印结果。
请注意,二分查找算法要求输入的数组必须是有序的。如果数组无序,则需要先对数组进行排序,然后再使用二分查找。不会排序的小伙伴可以戳这里学习桶排序哦!