二进制搜索假定你要搜索的数组(或任何其他数据结构)是有序的。
我们从数组和我们需要搜索的项目开始。
我们看一下数组的中间部分。想象一下,我们把数组的一部分放在左边,而另一部分放在右边。
如果我们拥有的项目比我们要找的项目低,那么它一定在右边的部分,所以我们可以完全抛弃右边的部分。
然后我们进行同样的操作,将数组的右边部分一分为二,看中间的项目,我们就可以丢弃数组的一部分。
最后,你会得到这个项目(如果没有找到这个项目,你会返回null )。
最后,如果数组有8个项目,我们最多只需4步就能找到该项目。
如果数组有32个项目,我们在最坏的情况下最多有6步。与线性搜索中的32个相比,这是一个巨大的优化!
二进制搜索的复杂度为O(log n) 。
下面是它的一个可能的实现。
const binarySearch = (list, item) => {
let low = 0
let high = list.length - 1
while (low <= high) {
const mid = Math.floor((low + high) / 2)
const guess = list[mid]
if (guess === item) {
return mid
}
if (guess > item) {
high = mid - 1
} else {
low = mid + 1
}
}
return null //if not found
}
这是怎么做的呢?我们得到list 数组,以及我们要找的项目值。然后我们将low 的值初始化为0,将high 的值初始化为列表中的最后一个索引。我们首先查看中间的项目,如果它是我们要找的,我们就返回它,然后我们就完成了。如果不是,我们设置low 或high 值,只看数组的左边或右边部分,我们重复这个过程,直到我们找到那个项目。
我们返回该项目在数组中的索引。
console.log(binarySearch([1, 2, 3, 4, 5], 1)) //0
console.log(binarySearch([1, 2, 3, 4, 5], 5)) //4
如果没有找到该元素,我们返回null 。
console.log(binarySearch([1, 2, 3, 4, 5], 6)) //null