1.定义
折半查找(也被称为二分查找)是一种在有序数组中查找特定元素的搜索算法。
搜索过程从数组的中间元素开始,如果中间元素正好是目标值,则搜索结束;
如果目标值大于或小于中间元素,则在数组大于或小于中间元素的那一半中查找,
而且同样从中间元素开始比较。
如果再次比较中间元素时,目标值仍大于(或小于)中间元素,则重复之前的过程,直到找到元素,或者搜索范围为空。
2.思想
折半查找的基本思想是将关键字与数组中间元素进行比较,
如果等于则查找成功;
否则,利用中间元素将数组分为两半,
如果中间元素比关键字大,则在数组的前半部分继续查找;
如果中间元素比关键字小,则在数组的后半部分继续查找,直到找到为止。
3.举例
假设有一个已经排好序的数组[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],我们想要查找数字7:
-
首先,找到数组的中间元素。数组的长度是10,所以中间元素的索引是(0+9)/2=4(向下取整),中间元素是5。
-
5比我们要查找的数字7小,所以我们知道7肯定在数组的右半部分,也就是[6, 7, 8, 9, 10]。
-
接下来我们在新的数组[6, 7, 8, 9, 10]中查找7。这个数组的长度是5,所以中间元素的索引是(0+4)/2=2,中间元素是8。
-
8比我们要查找的数字7大,所以我们知道7肯定在数组的左半部分,也就是[6, 7]。
-
接下来我们在新的数组[6, 7]中查找7。这个数组的长度是2,所以中间元素的索引是(0+1)/2=0,中间元素是6。
-
6比我们要查找的数字7小,所以我们知道7肯定在数组的右半部分,也就是只剩下一个元素[7]。
-
最后,我们在数组[7]中查找7。这个数组只有一个元素,而且这个元素正好是我们要查找的数字,所以查找成功。
这就是折半查找的过程。每一次比较,都排除了一半的元素,所以折半查找的效率非常高。这种查找方式特别适合于数据量大且查找次数多的情况。
4.思路
-
确定查找范围:首先确定整个查找的范围,这个范围就是整个数组。
-
找到中间元素:找到这个范围的中间元素。
-
比较目标:将中间元素和我们要查找的目标进行比较:
-
如果中间元素就是我们要找的目标,那么查找成功,返回这个元素的位置。
-
如果中间元素比目标大,那么我们知道目标肯定在中间元素的左边,所以我们可以将查找范围缩小为左半部分。
-
如果中间元素比目标小,那么我们知道目标肯定在中间元素的右边,所以我们可以将查找范围缩小为右半部分。
-
-
重复查找:在新的查找范围中重复第2步和第3步,直到找到目标,或者查找范围已经缩小到无法再分,也就是说我们已经查找完整个数组但是没有找到目标。
5.代码
#include<stdio.h>
int binary_search(int *p,int value,int len){
int low = 0;
int high = len - 1;
int mid = 0;
while(low <= high){
mid = (high + low) / 2;//取中间位置
if(p[mid] == value)
return mid;//返回元素所在索引位置
else if(p[mid] > value)
high = mid - 1;//说明查找的元素在左边,所以右边界要变化
else
low = mid + 1;//说明查找的元素在右边,所以左边界要变化
}
return -1;
}
int main(){
int arr[5] = {10,23,45,67,100};
int len = sizeof(arr) / sizeof(arr[0]);
int value = 0;
int ret = 0;
printf("数组中的元素值为:");
for(int i = 0;i < len;i++)
printf("%d ",arr[i]);
printf("\n");
printf("请输入你要查找的值:");
scanf("%d",&value);
ret = binary_search(arr,value,len);
if(ret < 0){
printf("你想要查找的值 %d 不存在.\n",value);
}else{
printf("你要查找的值 %d 在索引位置 %d 处\n",value,ret);
}
return 0;
}
6.运行

7.优劣
优点:
-
查找速度快:每一次比较都能够排除掉一半的数据,所以查找速度非常快。
-
效率高:对于数据量大的情况,折半查找的性能优势更加明显。
缺点:
-
要求数据有序:折半查找的一个前提条件是数据必须事先排序。如果数据没有排序,我们需要先对其进行排序,这将增加额外的时间成本。
-
只适用于数组:折半查找需要随机访问元素,也就是说我们需要直接通过索引来访问元素。因此,折半查找只适用于支持随机访问的数据结构,比如数组。对于其他不支持随机访问的数据结构,比如链表,折半查找就无法直接应用。



2647

被折叠的 条评论
为什么被折叠?



