初识基础算法--二分查找(C++)

本篇文章可能只适用于刚刚接触二分查找算法的小白


一、二分查找

        二分查找又名折半查找,是一种效率较高的查找方法。但二分查找要求线性表必须是顺序存储结构,且表中元素按关键字有序排列。

二、二分查找过程

        从表的中间记录开始,先将线性表的中间元素的关键字与我们需要查找的给定关键字进行比较,如果给定关键字和中间记录的元素关键字相同,则查找成功;如果给定关键字比中间记录的关键字小,则往表的左边继续查找;如果给定关键字比中间记录的关键字大,则往表的右边继续查找。这样反复进行比较,直到查找成功,或着确认查找失败为止。

下面为演示过程:

012345678910
513192137566476808892

给定关键字 21,上面为有序表arr

在二分查找算法中,我们需要通过循环来逐步缩小查找范围,直到找到目标值或确定其不存在于数组中。

首先,我们初始化两个指针leftright,分别指向数组的首尾元素。这里我们使用arr.size() - 1来获取数组的最后一个元素的索引,因为arr是一个vector,我们可以利用vectorsize()成员函数来动态获取数组大小。

int left = 0, right = arr.size() -1;

接下来,我们进入循环,并在每次循环中计算中间位置mid。这里采用(left + right) >> 1的方式来计算mid.

int mid = left + right >> 1;

然后,我们比较arr[mid]与关键字21的大小关系。如果arr[mid]等于21,说明找到了目标值,我们输出其位置并退出循环。如果arr[mid]大于21,说明目标值应该在mid的左侧,因此我们将right更新为mid - 1。如果arr[mid]小于21,说明目标值应该在mid的右侧,因此我们将left更新为mid + 1

while (left < right) {
	int mid = left + right >> 1;
	if (arr[mid] == num) {
		cout << mid << endl;
		return 0;
	}else if (arr[mid] > num) {
		right = mid - 1;
	}
	else {
		left = mid + 1;
	}
}

循环继续进行,直到left大于right,跳出循环。

三、完整代码

#include<bits/stdc++.h>
using namespace std;
vector<int> arr = { 5, 13, 19, 21, 37, 56, 64, 76, 80, 88, 92 };//vector容器
int main() {
	int left = 0, right = arr.size() - 1;
	int num;
	cout << "请输入给定关键字:";
	cin >> num;
	while (left < right) {
		int mid = left + right >> 1;
		if (arr[mid] == num) {
			cout << mid << endl;
			return 0;
		}else if (arr[mid] > num) {
			right = mid - 1;
		}
		else {
			left = mid + 1;
		}
	}
	return 0;

 代码解释:这里使用了位右移操作 >> 来计算中间位置。left + right >> 1 相当于 (left + right) / 2。

四、总结

二分查找利用了线性表中元素的有序性,每经过一次比较就把线性表中的查找范围缩小一半,所以对于一次查找,无论成功还是失败,二分查找需要比较的次数都不会超过\left \lfloor \log \:n \right \rfloor+1,也就说明二分查找的平均查找长度为O(logN)。


因为作者本人也是刚刚接触算法,如有不对,希望大佬可以指出!!!

这里有更加详细的解释,如有不懂,可以继续参考:算法---二分算法-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值