二分查找也叫折半查找,是一种在相当大的数据规模下常用的高效率的查找方法。每次搜索范围减少一半,时间复杂度为 log n,不过在使用前数组必须排好顺序。
1.普通写法
function findIndex(arr, val, left = 0, right = arr.length - 1) {
if(left > right) return -1
let center = Math.floor((left + right) / 2)
// 防止溢出的写法: center = (left + right) >>> 1
if(arr[center] === val) {
return center
}else if(arr[center] > val) {
right = center - 1
}else {
left = center + 1
}
return findIndex(arr, val, left, right)
}
2.查找左边界
function findIndexLeft(arr, val, left = 0, right = arr.length - 1) {
if(left > right) return -1
let center = Math.floor((left + right) / 2)
if(arr[center] === val) {
while(arr[center - 1] === val) {
center--
}
return center
/* 另一种写法
if(arr[center - 1] === val) {
right = center -1
}else {
return center
}
*/
}else if(arr[center] > val) {
right = center - 1
}else {
left = center + 1
}
return findIndexLeft(arr, val, left, right)
}
3.查找右边界
function findIndexRight(arr, val, left = 0, right = arr.length - 1) {
if(left > right) return -1
let center = Math.floor((left + right) / 2)
if(arr[center] === val) {
while(arr[center + 1] === val) {
center++
}
return center
/* 另一种写法
if(arr[center + 1] === val) {
left = center + 1
}else {
return center
}
*/
}else if(arr[center] > val) {
right = center - 1
}else {
left = center + 1
}
return findIndexRight(arr, val, left, right)
}