在一个有序(升序或降序)的数组中查找指定的数字n,使用遍历数组(按数组下标的顺序一个个查找)的方法效率较低,而使用二分查找,每次可以排除一半的数据,效率较高。
比如:让你猜1~300中的一个数,你会1,2,3,4,5……这样猜吗?这样显然很慢。每次折半猜,第一次猜150,判断比目标数大了还是小了,若大了,就从1~150之间猜,第二次猜75,这样每次就排除了一半的数。
代码实现://arr 假设是1~10的数组
//n 要查找的值
//left 数组的左下标
//right 数组的右下标
先使left数组的首元素下标(也就是0),right等于末元素下标(数组元素个数-1,也就是下图中sz-1)。假设要找的值n=7,第一次进入while循环后,由于arr[mid]<n,这时可排除数组中mid之前(包括mid)的数,即left=mid-1。以此类推,直到left和right相等时,这次进入while循环后,若n=arr[mid],则表达else下的代码,若n!=arr[mid],则left会加1(或者right会减1),使得left>right,跳出循环。
#include <stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10};
int n = 0;
scanf("%d", &n);//输入要查找的值
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] < n)
{
left = mid + 1;//这里别忘了要加1,这个加1很关键,若不加1,当数组里找不到n时将无法跳出循环
}
else if (arr[mid] > n)
{
right = mid - 1;
}
else
{
printf("找到了,下标为%d\n", mid);
break;//这部分不能单独拿到外面(即将while括号里改为left=right),否则不好表示找不到的情况
}
}
if (left > right)
printf("找不到\n");
return 0;
}