002 二分查找法——“C”
一、二分法是什么?
本文仅是介绍朴素的二分查找,如果您想要查找左右端点http://t.csdnimg.cn/0GVrC请看这篇文章
1.二分查找算法,也称折半搜索算法 ,是一种在有序数组中查找某一特定元素的搜索算法。
2.二分查找法思路
举一个简单例子,10名同学,按1到10顺序站好,想要找到Fan这个人,将10人中间位置序号对应的名字与所要查找名字比较,如果两者相等,则查找成功;否则利用中间位置序号,分成前、后两个部分,如果中间位置序号大于查找名字对应的序号,则进一步查找前部分,否则进一步查找后一部分。重复以上过程,直到找到满足条件的名字,否则全部过程走完了,找不到名字。
二、使用步骤
代码如下(示例):
int mid_search(int arr[], int k, int sz) //定义二分查找函数
{
int left = 0; //定义数组元素最左侧下标为0
int right = sz - 1; //定义数组元素最右侧下标为总数-1
while (left <= right)
{
int mid = left + (right - left) / 2; //此表达式是防止int型溢出哦,也是求平均哈
if (arr[mid] < k)
{
left = mid + 1;
}
else if (arr[mid] > k)
{
right = mid - 1;
}
else
{
return mid; //找到了,返回下标
}
}
return -1; //过程全部走完了,没找到,返回-1;
}
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int k = 0; //定义想要查找的值
int ret; //定义返回值
int sz = sizeof(arr) / sizeof(arr[0]); // (sizeof是c语言的内置运算符,
以字节为单位给出指定类型的大小 ;求数组元素的总数==整个数列字节大小/一个元素的字节大小)
printf("请输入要查找的值\n");
scanf("%d", &k);
ret = mid_search(arr, k, sz); //用ret接收mid_search返回的值
if (ret == -1)
printf("没找到,请重新输入");
else
printf("找到了,下标为%d", ret);
return 0;
}
tips:这里的left,right,mid均是arr[]数组元素的下标
2.详细图解
---------------------------------------------------------------------------------------------------------------------------------
1、第一次二分查找
第一次平均值计算mid=left+(right-left)下标mid==4对应的值为5小于我们想要查找的数(7)
执行此语句段
---------------------------------------------------------------------------------------------------------------------------------
2、进行第二次二分查找法,此时左下标left由原来的0变为了5则前面的值(1,2,3,4,5)都可以舍去,因为我们想要查找的值(7)不在数值1到5的范围内。
——>第二次求平均值:下标:left(5)+(right(9)-left(5))/2=7,对应的数值为8,大于想要查找的值7
执行此语句段
查找的值在arr[mid]的左侧,因此arr[mid]右侧的值(8,9,10)可以舍去,进一步缩小查找范围
right=7-1=6
---------------------------------------------------------------------------------------------------------------------------------
3.进行第3次二分查找法
——>第三次计算平均值mid=left(5)+(right(6)-left(5))/2=5 对应的数值为6,小于7
执行此语句段
left=mid+1=6 注意此时right也等于6,满足循环条件
--------------------------------------------------------------------------------------------------------------------------------
4.进行第4次二分查找法
——>mid=left(6)+(right(6)-left(6))/2=6,此时arr[mid]=k(我们想要查找的值)
执行此语句段,表示arr[mid]=k这种情况,返回mid即目标值的下标,当然此刻
的left==right==mid==6.
if:输入值11,经过上面的二分查找循环后,则输出-1,因为没有在有序数组中找到该值