【C++算法】二分查找

二分查找(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;
}

代码解释:

  1. 定义了一个 binarySearch 函数,该函数接受一个整数数组 nums 和一个目标值 target 作为参数。

  2. 初始化左边界 left 为 0,右边界 right 为数组 nums 的最后一个元素的索引。

  3. 使用 while 循环进行搜索,直到左边界大于右边界时结束。

  4. 在循环内部,计算中间索引 mid。注意这里使用了 (right - left) / 2 而不是 (right + left) / 2,这是为了防止在 left 和 right 都很大时发生整数溢出。

  5. 检查中间元素 nums[mid] 是否等于目标值 target。如果是,则返回 mid

  6. 如果 nums[mid] 大于 target,则将搜索范围缩小到左半部分,更新右边界 right 为 mid - 1

  7. 如果 nums[mid] 小于 target,则将搜索范围缩小到右半部分,更新左边界 left 为 mid + 1

  8. 如果在循环结束时仍未找到目标值,则返回 -1。

  9. 在 main 函数中,创建了一个有序数组 nums 和一个目标值 target,然后调用 binarySearch 函数进行搜索,并打印结果。

请注意,二分查找算法要求输入的数组必须是有序的。如果数组无序,则需要先对数组进行排序,然后再使用二分查找。不会排序的小伙伴可以戳这里学习桶排序哦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值