文章目录

一、背景

  • 二分查找是算法课程入门阶段经常被提到的一种算法,我们对其代码模板也已经滚瓜烂熟了。
  • 本文将会通过一段简单的动画来模拟二分查找的实现,让我们可以更直观地理解这个算法的底层原理。

二、使用前提

  • 应用二分查找算法是有一定的使用前提的:
  1. 查找的对象可以通过索引访问(对象一般为数组)
  2. 存在左右边界(数组的左边界下标为0,右边界下标为数组长度减1)
  3. 最关键的是这个查找的对象要有次序(数组是顺序递增或顺序递减的)

三、动画实现

  • 请大家结合动画与下面的文字描述仔细体会一下二分查找的过程:查找的对象是一个1-10顺序递增的数组,查找的目标是3这个数:
  1. 首先找出数组的左边界下标L=0,数组的右边界R=9(数组长度为10减去1);
  2. 算出中间值mid:(L+R)/2=5(取整),将这个中间值做为下标,得到当前查找到的元素 [mid]=6;
  3. 将查找到的元素[mid]=6与目标值Target=3进行大小比较,发现目标值小于查找到的元素;由于对象数组是从左到右顺序递增的,说明我们最终要查找的目标值还在当前查找到的这个值的左边
  4. 这时候,我们把右边界R移动到当前中间值mid的左一格,即R=mid-1=4;
  5. 接下来重复第2步,算出中间值mid:(L+R)/2=(0+4)=2,将这个中间值做为下标,得到当前查找到的元素 [mid]=3;
  6. 将查找到的元素[mid]=3与目标值Target=3进行大小比较,发现目标值Target正好等于查找到的元素,大功告成。
  7. 用一段动画看清二分查找算法的原理_二分查找

四、代码模板

  • 真正理解了以上的二分查找的原理,我们就不难写出其实现代码了:
/**
* 二分查找法
* @param nums 从小到大排列的有序数组
* @param target 目标值
* @return 目标值所在数据的索引值,未找到返回-1
*/
public int search(int[] nums, int target) {
int l=0;
int r=nums.length-1;
while (l <= r) {
int mid = (l + r) / 2;
if (target == nums[mid]) {
return mid;
} else if (target > nums[mid]) {
l = mid + 1;
} else {
r = mid - 1;
}
}
return -1;
}
  • 大家也可以想象一下,如果这个数组我们反过来从大到小递减,上面的代码模板应该会发生什么改变?