二分法是什么?
在⼀个升序的数组中查找指定的数字n,很容易想到的方法就是遍历数组,但是这种方法效率比较低。
⽐如我买了⼀双鞋,你好奇问我多少钱,我说不超过300元。你还是好奇,你想知道到底多少,我就让你猜,你会怎么猜?你会1,2,3,4...这样猜吗?显然很慢;⼀般你都会猜中间数字,比如:150,然后看大了还是小了,这就是二分查找,也叫折半查找。
也就是说,用二分法可以轻松将数组的一半排除掉,那么我们如何实现呢?
详解:
我们可以定义一个整型数组 int arr [ ]
数组长度sz = sizeof(arr) / sizeof(arr[0])
我们可以指定数组的最左边元素下标为0,最右边则为(sz-1)(这是因为数组元素的下标总是从0开始)
则中间数字为mid =(left+right)/ 2
则数组元素下标为 0 1 2 3 4 5 6 7 8 9
第一次查找中间元素 mid=(0+9)/ 2=4;中间元素为5, arr [4] =5
5<7 ,说明需要查找数组的后半段;此时 left=mid+1=5,right不变;
此时查找的数据范围为 6~10 ,元素下标为 5 6 7 8 9
第二次查找中间元素 mid=(5+9)/ 2 = 7 ;中间元素为8, arr [7] =8
8>7 ,说明需要查找元素的前半段;此时left不变,right=mid-1;
此时查找的数据范围为 6~7 ,元素下标为 5 6
第三次查找中间元素 mid=(5+6)/ 2=5;中间元素为6,arr [5]=6
6<7 ,说明需要查找数组的后半段
同理,此时就可以查找到元素7的下标
注意:循环的条件是left <= right,此时两者中间至少还有一个元素
代码运行:
#include <stdio.h>
int main(){
int arr[]={1,2,3,4,5,6,7,8,9,10};
int k;
scanf("%d",&k);
int sz=sizeof(arr)/sizeof(arr[0]) ;
int left=0;
int right=sz-1;
while(left<=right){
int mid=(left+right)/2;
if(arr[mid]<k)
left=mid+1;
else if(arr[mid]>k)
right=mid-1;
else{
printf("找到了,下标为%d",mid);
break;
}
}
if(left>right)
printf("找不到");
return 0;
}
注:二分法只适用于有序数列(升序),如果是无序数列,可以进行遍历或排序
总结
以上就是今天要讲的内容,本文简单介绍了二分法的使用,方便查找数据