二分查找是一种高效的查找算法,也被称为折半查找,只适用于有序的线性表。相比顺序查找,二分查找的时间复杂度为 O(log n),可以快速地找到想要的元素。本文将从多个角度对二分查找进行例题分析。
一、二分查找基本思路
二分查找的基本思路是将有序的线性表一分为二,看待中间的元素,如果要查找的元素比中间元素小,则在中间元素的左边进行查找;如果要查找的元素比中间元素大,则在中间元素的右边进行查找。重复以上过程,直到找到要查找的元素或者已经查找完整个线性表。
二、简单的二分查找例题分析
下面我们通过一个简单的例题来进一步认识二分查找算法。
题目描述:给定一个有序的整数数组 nums,和一个目标值 target,请在数组中查找 target,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
示例:输入: nums = [1,3,5,6], target = 5;输出: 2。
二分查找的代码如下:
```
public int searchInsert(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return left;
}
```
从代码中可以看出,我们首先定义了左指针 left 和右指针 right,它们划定了一个查找区间 [left, right]。在每次循环中,我们都会取中间位置 mid,然后将 mid 所在的元素 nums[mid] 与要查找的元素 target 做比较。如果 nums[mid] 等于 target,则直接返回 mid。如果 nums[mid] 小于 target,则说明要查找的元素在 mid 右侧,所以将 left 赋为 mid + 1。如果 nums[mid] 大于 target,则说明要查找的元素在 mid 左侧,所以将 right 赋为 mid - 1。当 left 和 right 相交时,循环结束。最后,我们需要返回 left,它的含义是要插入的位置。
三、二分查找的时间复杂度
二分查找的时间复杂度为 O(log n),这是因为每次比较都可以把待查找区间缩小一半。首先,将查找区间缩小到两倍需要进行一次比较,缩小到四倍需要进行两次比较,缩小到 8 倍需要进行三次比较...总共需要进行的比较次数恰好是 log2 n,因此时间复杂度为 O(log n)。
四、二分查找的必要条件
二分查找必要条件是线性表中的元素必须是单调有序的,即从小到大或者从大到小排列。
五、二分查找的局限性
二分查找虽然可以快速地查找到目标元素,但是它的局限性也比较明显:
1. 二分查找只适用于有序的线性表。
2. 二分查找只适用于静态的查找表,也就是说一旦数据发生变化,比如插入、删除等操作,就需要重新构建查找表,这就增加了时间和空间的开销。
3. 二分查找的最终要求是查找到目标元素,而有时候我们并不需要找到目标元素。比如前面的例题,如果目标元素不存在于数组中,我们只需要找到插入该元素的位置即可。
微信扫一扫,领取最新备考资料