在一个有序数组里查找一个数字详解折半(二分)(算法)
分两种算法一种普通算法。一个一个遍历和,折半(二分)查找法提示:以下是本篇文章正文内容,下面案例可供参考
一、普通方法
遍历法这种一个一个遍历一个一个判断然后得到下标
int arr[] = { 1,2,3, 4,5,6,7,8,9, 10 };
int k = 7;
//写一个代码,在arr数组(有序的)中找到7
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sz; i++){
if (k== arr[i]){
printf("找到下标是: .%d\n",i);
break;
}
}
二、二分查找法(折半查找法)
1.一半再分一半
代码如下(示例):
int k = 6;
printf("请输入一个从1-10之间的要查找的数字=>");
scanf("%d", &k);
int arr[] = { 1,2,3,4,5,6,7,8,9, 10 };
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)
{ right = mid - 1;}
else if (arr[mid] < k)
{
left = mid + 1;
}
else
{
printf("找到了%d下标为", mid);
break;
}
if (left>right)
{
printf("找不到\n");
}
}
原理
原理在这个数组里{1,2,3,4,5,6,7,8,9,10}
除以一半可以大幅度的减少搜索范围,比如
我要从中找到4这个数字的时候,的时候先min=left + right整个数组折半找到中间这个5这个元素现在开始比较以确定下标的走向,
如果5比你找的这个4数字要小,好了确定范围在5,6,7,8,9,10,里这个范围里找,但是5>4要大所以这个范围就在1,2,3,4,5中找左边下标不用动右边下标减1right- -
min=left + right相加再折半
得到中间数字3这个时候又要确定走向3比4要小这个时候范围在3,4,5,这个范围里,下标走向是往左边走
右边下标不用动left++
min=left + right相加再折半最终这个min=4的时候arr[mid] > 和arr[mid] < k条件不成立了再判断left的数值是不是大于了right的值。因为如果这个条件成立了相已经把所有的可能的数字已经找完了
条件不成立那么这个min就是你要找的数字
总结
对这个数组一半一半的折半再判断下标的走向即可一步一步接近你要找的那个数字的下标
这个方法比遍历要快速不少
如果遍历的话需要遍历10个数字
而折半最大3步,例找6
(1,2,3,4,5,6,7,8,9,10)5
(6,7,8,9,10)8
(6,7)6