二分查找是一个高效的查找数据的方法,有多高效呢,中国14亿人,你要寻找一个人,用暴力查找需要14亿次,但用二分查找,只需要使用31次,是不是很便利,让我们来解析二分查找吧。
二分查找,也叫折半查找,它的每一次查找,都会将数组折半,即对折以此,故叫折半查找,对折的好处就是排除了一半的数据,每一次查找都会折半,都会排除一半的数据,具体如何实现,我们来看看。
(1)准备:因为要对折数组,我们首先需要知道数据的长度,它的左边界与右边界,并且记住这个两个边界。
int arr[10]={1,2,3,4,5,6,7,8,9,10};//创建一个长度为10的数组
int sz=sizeof(arr)/sizeof(arr[0])//计算数组长度并保存
int right=0;//这是右边界,用变量right保存,方便记忆
int left=sz—1;//这是左边界,边界就是下标,数组最右边下标是数组长度减去一,所以此处是sz-1
(2)流程:用左右边界求出中间值,这样就求得中间下标,通过中间下标,我们可以找到数组中间元素,再用这个元素去和我们查找的数据去进行大小对比
情况1:如果查找的数据大于这个元素,那么,要查找的数据就在中间元素的右边,
情况2:如果小于就在中间元素的左边:。
第一次查找会排除一半的数据,就是这么来的,第一次查找后,我们需要进行第二次查找,这时候就需要重新确定左右的边界值,如果是情况1,那么右边界不变,左边界就是原来的中间值加1,想象一下,情况1中,你已经知道中间值左边的元素中没有你想要的答案,这时候就需要舍弃左边的元素,你又已经知道中间值也不是你想要的答案,那么答案就在中间值的右边,也就是加1,就确定了左边界,右边界不变,同理,如果是情况二,变的就是右边界,此时右边界就是中间值-1,不断折半,我们不难发现,这是一个循环过程,其中,中间值,左边界,和右边界,其中总有两个变量在变化,不断的排除,不断判断,就会越来越接近我们的答案。
int middle=(left+right)/2;//方式1
int middel=left+(right-left)/2;//方式2
求中间值有两种方法,但比较一下,我们应该选择方式2,因为相对于方式1,方式2数据溢出的可能性大一些,会发生丢失,因为left加上right可以大于int表示的最大范围,发生溢出,而方式2则减小了这个可能性。
(3)结尾:跳出这个循环,一自然就是找到我们想要数组元素,这时候我们可以用break语句打破循环,二是不断折半,折半到最后一个元素,仍然没有找到我们的答案,这是最后一次循环,此时左边界已经等于右边界了,代表数组元素已经排查完了,结束了,左边界加1,大于右边界,或者右边减去一,小于左边界,故得,二是左边界大于右边界,代表数组已经找完了,仍没有找到答案。
代码如下
#include<stdio.h>
int main()
{
int a[10] = {11,22,33,44,45,311,994,1231,2341,8889};
int right = 0;
int left = 0;
int sz = sizeof(a) / sizeof(int);
right = sz - 1;
int x = 0;
printf("要查找的数是:>>");
scanf("%d", &x);
while (left <= right)
{
int middle = left + (right - left) / 2;
if (x > a[middle])
left = middle + 1;
else if (x < a[middle])
right = middle - 1;
else if (x == a[middle])
{
printf("%d", a[middle]);
return 0;//找到了,直接结束程序
}
else
;
}
//找不到,跳出循环
printf("找不到\n");
return 0;
}
注意:二分查找只针对有序数组,不是有序数组不行。