引言
通常我们在查找数据中的某个数,一般最简单最直接的方法就是遍历,把数组中的每一个元素和要查找的数作比较,这样的查找对于小的数据来说可以行的通,但是对于庞大的数据就行不通,会严重影响效率,而二分查找法会事半功倍。
介绍
二分查找法也叫做折半查找法,在生活中我们猜数字,不可能是1,2,3,……这样的猜,一般都会是取中间的数字猜,再看是大了还是小了,再继续在排除的范围内猜中间数,这样就快的多,但是二分查找法只限于在有序序列中查找。
思路
比如现在有这样的一组数组
int arr[10] = { 1,4,6,7,8,9,10,15,22,43 };
我们使用二分查找法查找“15”这个数字,并返回它的下标
先创建两个变量指向此数组的最左边和最右边,再创建一个变量mid存中间元素
int left = 0;//第一个元素的下标
int right = sizeof(arr) / sizeof(arr[0]) - 1;//得到最后一个元素下标
int mid = 0;//记录中间元素的下标
mid = (left + right) / 2;//中间元素下标
我们的图大概就是这样的
此时arr[mid]=8,小于要查找的数“15”,所以在8和8以前的位置我们都要排除。现在查找的范围就在这里 ,缩小了一半,如下图
更新下标范围
left = mid+1;//如果arr[mid]的比要查找的数字小,就改左边下标
right = mid-1;//如果arr[mid]的比要查找的数字大,就改右边下标
很明显,这里需要一个循环,直到找到下标为止,而进入循环的条件就是,左边的下标小于或等于右边的下标:left<=right。
循环代码如下:
while(left<=right)
{
mid = (left + right) / 2;
if (arr[mid] == key)//key存放的是要找的数,我们这里是“15”
{
printf("找到了下标是%d",mid);//找到了就打印下标
}
else if (arr[mid] > key)
{
right = mid-1;
}
else if (arr[mid] < key)
{
left = mid+1;
}
}
找到了,就返回下标,没找我们让程序也要有一个反馈,这里我们创一个flag变量,初始化为0,找到了就让它自加,如果没找到它仍然是“0”,待整个循环结束后再判断。
if(1 == find )
printf("找到了,下标是%d\n", mid);
else
printf("找不到\n");
整体代码如下:
int main()
{
int arr[] = {1,4,6,7,8,9,10,15,22,43};
int left = 0;
int right = sizeof(arr)/sizeof(arr[0])-1;
int key = 7;//要找的数字
int mid = 0;//记录中间元素的下标
int find = 0;
while(left<=right)
{
mid = (left+right)/2;
if(arr[mid]>key)
{
right = mid-1;
}
else if(arr[mid] < key)
{
left = mid+1;
}
else
{
find = 1;
break;
}
}
if(1 == find )
printf("找到了,下标是%d\n", mid);
else
printf("找不到\n");
}