二分法
假设有一组数
123456
我们想要找出其中的一个数,用人的思维来想,我们就会直接去寻找与目标数一样的数,但是计算机不能和人的思维一样。
有一种常见得计算机思维就是依次查找
从第一个元素开始到最后一个元素,其中如果有元素与目标元素一样,那么就结束查找,我们可以利用循环来查找;下面看代码;
#include<stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,6 };
int k;
scanf("%d", &k);
int sz;
sz = sizeof(arr) / sizeof(arr[0] - 1);//这里求得是数组的长度,-1就是数组的个数从下标0开始
for (int i = 0; i <= sz; i++)
{
if (arr[i] == k)
{
printf("该数字的位置%d", i);
}
}
return 0;
}
这种方法比较容易理解;
就是依次遍历,最后寻找到我们想要的数
但是如果我们要查找的数字,比较多。例如几万个数。
计算机就得从1一直遍历到几万,会给计算机增加负担。
所以我们可以优化算法;
有一个比较通用且实用的思想,那就是二分查找;
还是举个例子
有一组数
1 2 3 4 5 6
我们可以将两边的值单独设置出来
left right
我们要求4的位置
设置一个中间值
mid = (left/right) / 2
mid小于要求的数,我们就可以把left加上1,一下就可以排除掉一大半的数字;
mid大于要求的数,我们就可以把right减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 (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;
}