我们定义了一个有序数组,我们要找到这里面的一个数字,我们要怎么去做呢?
比如我们定义了一个数组:
int arr[]={1,2,3,4,5,6,7,8,9,10}
我们要去找到这里面的7这个数字,我们可以怎么做呢?
我们可以直接去遍历,我们定义一个变量k=7
遍历的完整算法如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int k = 7;
int sz = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < sz; i++)
{
if (k = arr[i])
{
printf("找到了");
break;
}
}
return 0;
}
但是我们除了这种遍历之外还有没有其它好的方法呢?
有的!那就是用二分查找的办法,也叫折半查找
它的时间复杂度是log以2为底的n次幂
思路:通过数组的左右下边来确定这个数字
完整算法实现:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int k = 7;
int sz = sizeof(arr) / sizeof(arr[0]);
int left = 0;
int right = sz - 1;
while (left <= right)
{
int mid = (left + right) / 2;
if (k > arr[mid])
{
left = mid + 1;
}
else if (k < arr[mid])
{
right = mid - 1;
}
else
{
printf("找到了,下标是%d\n", mid);
break;
}
}
if (left > right)
{
printf("找不到");
}
return 0;
}
这里面注意点有这个循环的条件判断,一定是left<=right
还有就是这个mid的定义一定要写在循环的内部,因为mid是要重复计算的。
大家可以看下我发的图来理解,也可以自己画图去理解: