定义
二分查找算法在维基百科中的定义如下:
在计算机科学中,二分查找算法(英语:binary search algorithm),也称折半搜索算法(英语:half-interval search algorithm)[1]、对数搜索算法(英语:logarithmic search algorithm)[2],是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。
从上述定义可以知道,二分查找算法的前提条件是:查找的数组必须是一个有序数。
算法步骤
-
从数组中可知对比范围是 ( 到 的闭区间)
-
由左右边界可求出中间值的索引值为
-
将目标值 与 进行对比,并判断 与 的大小,根据结果作出以下行动
- 相等,终止查找,输出 的索引值
- 大于 ,令 等于 ,重复步骤 1
- 小于 ,令 等于 ,重复步骤 1
流程图
代码实现
/**
* 查找数据中特定的值
* @param {Array<number>} arr 数组
* @param {number} target 需要查找的值
* @returns {number} 数组中等于target的索引值
*/
function binarySearch(arr, target) {
let start = 0;
let end = arr.length - 1;
let mid;
while (start <= end) {
mid = start + Math.floor((end - start) / 2) ;
if (arr[mid] === target) {
return mid;
} else if (arr[mid] > target) {
end = mid - 1;
} else if (arr[mid] < target) {
start = mid + 1;
}
}
return -1;
}
let arr = [1, 2, 3,7,9,44,55,312,777,7892];
let target = 7892;
console.log(binarySearch(arr, target));
扩展
在求一些特殊的结果时,可以使用二分查找而忽略这个前提条件,如下例
给定一个无序数组 nums[],相邻数字不同。返回任意一个局部最小值。局部最小值的定义为:
- 对于第一个元素 而言,只要它比 第二个元素要小,则就是局部最小值。
- 对于最后一个元素 而言,只要它比 倒数第二个元素要小,则就是局部最小值。
- 对于数据中间的元素,如果一个数相邻的两个数都比他大,那么他就是局部最小值。
上述条件如下图
如果你还记得抛物线,这就是找一个开口朝上的抛物线。下面说说解决具体思路
代码实现
function LocalMinimum (arr, i) {
if (arr[0] < arr[1]) {
return {
value: [arr[0], arr[1]],
index: 0
}
};
if (arr[arr.length - 2] > arr[arr.length - 1]) {
return {
value: [arr[arr.length - 2], arr[arr.length - 1]],
index: arr.length - 1
};
}
let start = 0;
let end = arr.length - 1;
while (start < end) {
let mid = start + ((end - start) >> 2);
if (arr[mid - 1] < arr[mid]) {
end = mid;
}else if (arr[mid + 1] < arr[mid]) {
start = mid;
}else {
return {
value: [arr[mid - 1], arr[mid], arr[mid + 1]],
index: mid,
};
}
}
}