友友们,今天和大家一起来实现C语言中很常见的一种查找方式——二分查找,希望接下来的内容能让大家有收获。
目录
二分查找的简单介绍
二分查找是一种常见的查找方式,又被称为折半查找。他是一种高效的查找方式,适用于已排序的有序数组。二分查找通过将目标值与数组的中间元素相比较,从而将查找范围缩小了一半,直到找到目标值或确定目标值不存在为止。
注意:二分查找效率虽高,但条件要求苛刻,必须是有序数组
二分查找的优势
当我们见朋友买了一件衣服,问朋友衣服的价格,朋友说不超过200元,让你猜猜。这时我们应该怎么猜才能效率最高,是从1~200一个一个数问过去还是每次都猜中间数?
答案是:每次都猜中间数。
一个一个数猜就是我们常见的遍历法,效率低下。在查找对象是有序数组的前提下,我们选择使用二分查找法,每一次查找都可以缩小一半的查找范围,更高效更便利。
二分查找的实现
1、首先我们给出一个有序数组,并给出一个想要在这个数组中查找的数。
#include<stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int k = 0;
scanf("%d", &k);
//给出一个1-10的有序数组,在里面查找k
return 0;
}
2、实现“二分”
二分查找的重点在于将查找数“二分”,我们首先计算出数组长度,将数组最左端下边赋给left,将数组最右端下标赋给right,计算出二者的中间值。
int N = sizeof(arr)/sizeof(arr[0]); //计算出数组内元素个数
int left = 0; //数组最左端下标为0
int right = N - 1; //数组最右端下标为数组总元素个数减1
int mid = (left + right) / 2; //数组中间值为二者相加再除2
相信大多数人的第一想法会是像上述代码所示,但这样做会存在一个问题,如果在运算过程中,两个数都很大,相加的值可能会溢出,导致两数相加再除以二不是他们的平均值,从而出现错误。所以我们需要对其进行完善,避免程序运行中可能出现的问题。
所以这方面的代码可优化为:
int N = sizeof(arr)/sizeof(arr[0]); //计算出数组内元素个数
int left = 0; //数组最左端下标为0
int right = N - 1; //数组最右端下标为数组总元素个数减1
int mid = left+(right-left)/2;
3、循环查找
实现了二分之后我们就要开始利用二分来进行查找,这里我们借助while循环来实现。我们将查找对比的过程放进while循环中,循环能够进行的条件是查找的范围中还有数。如果在数组范围内都没找到所查找的数,就证明这个数不在数组中,既查找失败。
图解一,能找到:
图解二,未到找:
用代码将上述思路实现:
#include<stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int k = 0;
scanf("%d", &k);
//给出一个1-10的有序数组,在里面查找k
int N = sizeof(arr)/sizeof(arr[0]); //计算出数组内元素个数
int left = 0; //数组最左端下标为0
int right = N - 1; //数组最右端下标为数组总元素个数减1
int mid;
int flag = 0;
while (left <= right) //确保查找范围不为空
{
mid = left + (right - left) / 2;
if (arr[mid] > k)
{
right = mid - 1;
}
else if (arr[mid] < k)
{
left = mid + 1;
}
else
{
printf("找到了,下标为:%d\n", mid);
flag=1;
break;
}
}
//如果找到了flag被修改为1 不会执行该语句
//若没找到flag仍为0 则会打印‘没找到’
if (flag == 0)
{
printf("没找到\n");
}
return 0;
}
代码的运行
若我们准备在数组{1,2,3,4,5,6,7,8,9,10}中查找k=7
若我们准备在数组 {1,2,3,4,5,6,7,8,9,10}中查找k=12
由此可证明这个代码成功实现了我们的需求。
以上就是 C语言基础:二分查找(折半查找)的实现及细节分析 的全部内容了,希望对你有所帮助!