二分查找及其时间复杂度的计算
什么叫二分查找?
二分查找也叫折半查找,是一种效率较高、查找次数较少的查找方法,查找时数据必须要求有序,举个例子:假如说张三买了一双鞋,张三要李四猜一下鞋的价格,范围在0~500之间,那么李四在猜的时候肯定不会从0开始一个个问,而是可能从一个中间值开始猜,这种方法就可以叫做二分查找。
二分查找的代码实现
假如说我们要在一个有序数组arr[]={0,1,2,3,4,5,6,7,8,9};
中查找数字7,我们就可以用二分查找来做;
1、定义变量作为数组下标
定义两个变量来存储该数组第一个元素的下标(left)以及最后一个元素的下标(right),再定义一个变量mid来存储该数组中间元素的下标,而mid=(left+right)/2;
2、判断循环条件
将left<=right作为while循环的循环条件;
3、arr[mid]与k进行对比
将中间元素arr[mid]与我们要查找的数k相比,若前者较小,则将mid的值赋给left,相当于把小于或等于arr[mid]的数全部舍弃,再将left++作为折半后的数组中最左边元素的新下标;
同理,若arr[mid]大于k,则将mid的值赋给right,相当于把大于等于arr[mid]的数全部舍弃,再将right++作为折半后的数组中最右边元素的下标;循环即可
4、若找得到,输出k的下标;若找不到,返回信息。
若找到最后arr[mid]=k,则说明k已找到,其下标就为mid;若left>right,则说明该数不在该数组中,也就是在该数组中找不到这个数。
图示:
实例代码如下:
#define _CRT_SECURE_NO_WARNINGS
//二分查找
#include<stdio.h> //printf
void Find_Num(int arr[], int sz, int k)
{
int left = 0; //数组中的首元素的下标 arr[0]
int right = sz - 1; //数组中的最后一个元素的下标 arr[sz-1]
int mid = 0; //数组中的中间元素的下标 arr[mid]
while (left <= right)
{
mid = (left + right) / 2;
if (arr[mid] < k)
{
left = mid;
left++;
}
else if (arr[mid] > k)
{
right = mid;
right--;
}
else
{
printf("找到了,下标为:%d\n",mid);
break;
}
if (left > right)
{
printf("找不到\n");
break;
}
}
}
int main()
{
int k = 0;
printf("请输入将要查找的数字:\n");
int arr[] = { 0,1,2,3,4,5,6,7,8,9 };
int sz = sizeof(arr) / sizeof(arr[0]);
while (scanf("%d", &k) != EOF)
//输入要查找的数
{
Find_Num(arr, sz, k);
//二分查找
}
return 0;
}
输出结果:
计算二分查找的时间复杂度
二分查找的本质无非就是将范围折半缩小,我们设一个数组内有n个元素,则最坏的查找情况就是n/2、n/4、n/8...一直到1为止,因此我们可以看出,每次查找时分母都会乘以2,设查找次数为x,则可以列出如下等式:
化简一下:
两边取对数:
省略底部的底数(通常计算时间复杂度时,对数的底数的2可以省略):
因此二分查找的时间复杂度就为:
二分查找的介绍到这里就结束了,如果你觉得本篇文章对你多少有些帮助,可以点个赞或者收藏一波支持一下哦,欢迎各位大佬批评指正,咱们下次再见!