一:折半查找概念
折半查找(也称为二分查找)是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是目标值,则搜索过程结束;如果目标值大于或小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且同样在那一半的中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。
二:折半查找的步骤
前提条件:数组必须是有序的。
确定搜索范围:初始化搜索范围的左边界
left
为数组的第一个元素索引,右边界right
为数组的最后一个元素索引。计算中间位置:计算中间位置
mid
,通常使用(left + right) / 2
的方式,为了避免整数溢出,也可以写作left + (right - left) / 2
。比较中间元素:将目标值
target
与中间位置mid
对应的元素进行比较。
- 如果相等,则搜索成功,返回
mid
。- 如果目标值小于中间元素,则更新右边界
right = mid - 1
,在左半部分继续查找。- 如果目标值大于中间元素,则更新左边界
left = mid + 1
,在右半部分继续查找。循环搜索:重复步骤 3 和 4,直到找到目标值或者搜索范围为空(即
left > right
)。搜索失败:如果搜索范围为空,则目标值不在数组中,返回 -1 或其他表示未找到的值。
三.折半查找案例分析
例如:在数组array = {4, 5, 6, 7, 9, 12, 18, 23}中查找9,其代码实现如下
public class BinarySearch {
// 声明一个静态变量来记录比较次数
public static int comparisonCount = 0;
public static int binarySearch(int[] array, int target) {
if (array == null || array.length == 0) {
comparisonCount = 0; // 数组为空,设置比较次数为0
return -1; // 数组为空,返回-1表示未找到
}
int left = 0;
int right = array.length - 1;
while (left <= right) {
comparisonCount++; // 每次比较时增加计数
int mid = left + (right - left) / 2; // 防止溢出
if (array[mid] == target) {
return mid; // 找到目标,返回其索引
} else if (array[mid] < target) {
left = mid + 1; // 在右半部分继续查找
} else {
right = mid - 1; // 在左半部分继续查找
}
}
return -1; // 没有找到目标,返回-1
}
public static void main(String[] args) {
int[] array = {4, 5, 6, 7, 9, 12, 18, 23};
int target = 9;
int result = binarySearch(array, target);
if (result != -1) {
System.out.println("元素 " + target + " 在数组中的索引为: " + result + " 查找的次数:" +comparisonCount);
} else {
System.out.println("元素 " + target + " 不在数组中" + "查找的次数" +comparisonCount);
}
}
结果如下:
四:折半查找的图解
五:折半查找的时间复杂度
折半查找的时间复杂度为 O(log n),可以考虑哈希表等其他数据结构提高效率