如果想在一个升序数组中查找一个我们想要的数据,我们能想到的方法大多是遍历一遍数组,但是这样的话最坏的情况需要遍历到最后一个数据才能找出我们想要的那个数据。在这里我想介绍一种方法——二分查找,也叫做折半查找
所谓二分查找,就是将若干个数组里面的数据依次对半分开
例如:有一个数组arr[]={1,2,3,4,5,6,7,8,9,10},我们想要从中查找 7 这个元素并知道他的下标,我们可以将这10个元素分成两半,我们可以定义数组的左边下标为left=0,右边的下标为right=9
通过元素的下标我们可以知道(0+9)/2=...1 ,我们找到下标为4的元素为5,我们把它定义为中间值mid,这个中间值mid<7也就是我们要查找的元素,因为是升序数组,所以可以推断我们要查找的元素不可能出现5以及5左边之前的元素
因此我们下次对半分最左边可以从下标为5(4+1)的元素开始,此时left=5,right=9,(5+9)/2=7,下标为7的元素为8,8>7,因此8以及8右边的元素可以排除,此时还剩下下标为5,6的元素,此时left=5,right=6(7-1),mid=(5+6)/2=5...1,下标为5的元素为6<7,所以5也排除,left=6(5+1),right=6,mid=(6+6)/2=6,下标为6的元素为7就是我们要查找的元素,程序完成
这样通过4次二分我们就找到了我们想要的结果,大大提高了效率
代码示例:
#include <stdio.h>
int bin_search(int arr[], int left, int right, int key)
{
while (left<=right)
{
int mid = (left + right) / 2;
if (arr[mid]==key)
{
return mid;
}
else if (arr[mid]<key)
{
left = mid + 1;
}
else if (arr[mid]>key)
{
right = mid - 1;
}
}
return -1; //当左下标大于右下标的时候,表示找不出元素,程序结束
}
int main()
{
int arr[] = {2,5,6,9,20,23,34,36,38,49 };
int length = sizeof(arr) / sizeof(arr[0]);//数组的长度
int key;//要查找的数字
int left = 0;//数组的左下标
int right = length - 1;//数组的右下标
printf("输入要查找的数字:\n");
scanf("%d", &key);
int answer=bin_search(arr, left, right, key);//一定要定义一个数录入函数返回的值,不然不会有结果
printf("%d", answer);
return 0;
}
结果如下: