二分查找

120 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第24天,点击查看活动详情

二分查找也被称为折半查找(Binary Search),它是一种效率比较高的查找方法,但它的前提是数据结构必须是有序的,二分查找可以在数据规模的对数时间复杂度内完成查找。但是,二分查找要求线性表具有有随机访问的特点(例如数组),也要求线性表能够根据中间元素的特点推测它两侧元素的性质,以达到缩减问题规模的效果。

简单来说,二分查找描述了在有序集合中搜索特定值的过程。下面来看下二分查找的具体过程。

二分查找中使用的术语:

下面是在二分查找中会用到的一些术语:

  • 目标 Target:你要查找的值
  • 索引 Index:你要查找的当前位置
  • 左、右指示符 Left,Right:我们用来维持查找空间的指标
  • 中间指示符 Mid:我们用来应用条件来确定我们应该向左查找还是向右查找的索引

它是如何工作的:

二分查找会在一个查找空间中进行操作,所谓的查找空间是指具有指定左索引和右索引的连续序列。

二分查找通过维护查找空间的左、右和中间指示符,并将查找目标(或某种条件)和中间值进行比较,如果条件不满足或值不相等,则清除目标不可能存在的那一半,并在剩下的一半上继续查找,直到成功为止。如果最后集合变为空还没有找到,那表示查找失败,无法找到目标。

下面我们来看下二分查找的代码实现:

function binarySearch(nums, target){
  if(nums == null || nums.length == 0)
    return -1;

  let left = 0;
  let right = nums.length - 1;
  while(left <= right){
    let mid = left + (right - left) / 2;
    if(nums[mid] == target){ return mid; }
    else if(nums[mid] < target) { left = mid + 1; }
    else { right = mid - 1; }
  }
  return -1;
}

由上述代码可以看到,二分查找的几个关键点:

  1. 初始条件:left = 0, right = length-1,也就是初始查找空间是集合的开始和结尾,也即整个数据
  2. 终止:left > right
  3. 向左查找:right = mid-1,查找空间舍弃右半边,选择左半边
  4. 向右查找:left = mid+1,查找空间舍弃左半边,选择右半边