什么是二分查找?
二分查找也称折半查找,它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。
原理:
我们将要查找的元素的值和数组中间位置的元素的值进行比较,如果比中间的元素大,则在有序数组的后半部分进行查找;如果中间位置的元素的值小,则跟有序数组的前半部分进行比较;如果相等,则找到了比较元素的位置.
应用:
假如有这样一个有序数组:
int arr【】= {1,2,5,6,7,9,11,15,16};
让你在这个数组里面将数字9找到并打印出来你会怎么做?
我们首先想到的会是将数组遍历,然后将每一个数进行判断。符合条件的就拿出来打印?
#include<stdio.h>
int main(void)
{
int arr[]={1,2,5,6,7,9,11,15,16};
int input,i,sz;
sz = sizeof(arr) / sizeof(arr[0]);
printf("输入要查找的数>>");
scanf("%d",&input);
for (i = 0 ;i<sz ;i++)
{
if(input == arr[i])
{
printf("找到了,下标是%d",i);
break;
}
else
{
printf("没找到!");
break;
}
}
return 0;
}
这样做确实是可以,但是这样做的效率很低。什么意思?
如果要查找的是1,那不用说确实很快,但是如果要找的是16呢,是你数组的最后一个数呢。
就我们举例的这个数组来说是不是你至少得找9次才能找到,那如果我们这个数值里面有成千上万个数那我们这样写代码是不是显得有点不太聪明?
这个时候我们就得想办法来提高我们得效率了,怎么提高?
二分查找
#include<stdio.h>
int main(void)
{
int arr[]={1,2,5,6,7,9,11,15,16};
int input,i,sz;
sz = sizeof(arr) / sizeof(arr[0]);
int left = 0;//数组最左边的值的下标
int right = sz -1;//数组最右边的值的下标
printf("输入要查找的数>>");
scanf("%d",&input);
while(left<=right)
{
int mid = (left + right) / 2;//先创建变量来存储数组中间值的下标
if(input < arr[mid])//如果要查找的数小于中间值
{
right = mid -1;//将数组最右下标改为中间值-1
}
else if(input > arr[mid])//如果要查找的数大于中间值
{
left = mid+1;4;//将数组最左下标改为中间值+1
}
else//除去大于小于就剩等于了,那么就找到了
{
printf("找到了!下标是%d",mid);
break;
}
}//程序跳出循环到这一步时会有两种情况,
//一种是我们找到了我们想要的数跳出来了这个时候left和right的关系是left<=right,
//还有一种是没找到我们想要的数也会到这来left和right关系是left>right,
//这时候就需要判断一下。
if(left>right)
printf("找不到!");
return 0;
}
这就是二分查找
当然如果为了后续的方便把也能封装成一个函数,这样就更加方便了。