一、什么是二分查找?
二分查找,又称为折半查找,是一种在有序数组中查找指定目标的搜索算法。该算法通过将目标值与数组中间的元素进行比较来逐步缩小搜索范围,直到找到目标元素或发现其不存在为止。
二、二分查找的原理
二分查找的基本原理如下: 1、确定要查找区间的左右端点 left 和 right;
2、计算中间位置 mid = (left + right) / 2;
3、比较中间位置 mid 的值和要查找的目标值 target:
(1)如果 mid 的值等于目标值 target,则找到了目标值;
(2)如果 mid 的值大于目标值 target,则在左半边的区间 [left, mid-1] 继续查找;
(3)如果 mid 的值小于目标值 target,则在右半边的区间 [mid+1, right] 继续查找;
4、重复上述步骤,直到找到目标元素或者区间不存在为止。
简单来说就是每次找到区间的中位数,判断该中位数是否是目标值,若不是则确定新的区间范围再寻找其中位数。以此类推,直到找到目标值为止。
三、二分查找图解
四、二分查找的实现
// 二分查找函数,arr为有序数组,n为数组长度,x为目标值
int binarySearch(int arr[], int n, int x)
{
int left = 0; // 左端点初始值为数组起点
int right = n - 1; // 右端点初始值为数组终点
while (left <= right)// 当左端点小于等于右端点时循环
{
int mid = left + (right - left) / 2; // 计算中间点位置
if (arr[mid] == x) // 如果中间点等于目标值,则返回中间点下标
{
return mid;
}
else if (arr[mid] < x) // 如果中间点小于目标值,则在右半段继续搜索
{
left = mid + 1;
}
else // 如果中间点大于目标值,则在左半段继续搜索
{
right = mid - 1;
}
}
return -1; // 如果未找到目标值,则返回-1
}
五、完整代码示例
从 {1,2,3,4,5,6,7,8,9} 中找到3的下标
#include <stdio.h>
int binarySearch(int arr[], int n, int x)
{
int left = 0;
int right = n - 1;
while (left <= right)
{
int mid = left + (right - left) / 2;
if (arr[mid] == x)
{
return mid;
}
else if (arr[mid] < x)
{
left = mid + 1;
}
else
{
right = mid - 1;
}
}
return -1;
}
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9 }; // 有序数组
int n = sizeof(arr) / sizeof(arr[0]); // 数组长度
int x = 3; // 目标值
int result = binarySearch(arr, n, x); // 调用二分查找函数
if (result == -1) // 如果返回-1,则说明未找到目标值
{
printf("Element is not present in array");
}
else //否则,返回目标值在数组中的下标
{
printf("Element is present at index : %d", result);
}
return 0;
}
结果
六、二分查找的优缺点
优点:
1、时间复杂度为O(logn),是一种非常高效的查找算法。
2、 可以应用于静态数组和有序链表中,在已经排好序的序列中进行二分查找具有相当高的性能,比如可以在很大的数据集合中快速地定位某一元素。
缺点:
1、要求待查找的序列必须是有序的。如果不是有序的,则需要先排序,增加时间和空间复杂度。
2、数组大小是固定的,不能动态调整。如果数据量较大,就需要占用更多的内存空间来存储。
3、只适用于单个元素的查找,对于区间查找、前缀匹配等问题无法直接使用。
4、当数组中存在重复元素时,查找结果可能不是唯一的,需要对查找结果进行处理。