赞
踩
二分查找法又称为折半查找,适合对已排序好的数据集合进行查找,时间复杂度为O(log2n)
//升序数组的二分查找法
function binarySearch(key, arr, begin, end)
{
if(begin > end) //数组为空,找不到目标元素
return -1;
var mid = (begin+end) >> 1;
if(key == arr[mid])
return mid; //返回元素位置
else if(key < arr[mid]) //小于则去左数组找
return binarySearch(key, arr, begin, mid-1);
else //大于则去右数组找
return binarySearch(key, arr, mid+1, end);
}
//升序数组的二分查找法
function binarySearch(key, arr)
{
var begin = 0, end = arr.length - 1;
while(begin <= end){
var mid = (begin+end) >> 1;
if(key == arr[mid])
return mid;
else if(key < arr[mid])
end = mid-1;
else
begin = mid+1;
}
return -1;
}
比如有序数组 nums = [1,2,2,2,3],target = 2,此算法返回的索引是 2。但如果想得到 target 的左侧边界,即索引 1,或想得到 target 的右侧边界,即索引 3,这样的情况此算法无法处理
//升序数组 function binarySearch(key, arr) { var begin = 0 var end = arr.length; //注意点1 while(begin < end){ //注意点2 var mid = (begin+end) >> 1; if(key == arr[mid]) end = mid; //注意点3 else if(key < arr[mid]) end = mid; //注意点4 else if(key > arr[mid]) begin = mid+1; } return arr[begin] == key ? begin : -1; //注意点5 }
注意点:
end = arr.length
,令搜索数组的区间变为[begin, end)
左闭右开while(begin < end)
,因为需要当begin == end
时则跳出循环,此时搜索区间为[begin, begin)
即为空end = mid
,向左缩小搜索范围,查找中间元素左边是否有相同的元素[begin, end)
左闭右开,所以是end = mid
而不是end = mid-1
//升序数组 function binarySearch(key, arr) { var begin = 0 var end = arr.length; while(begin < end){ var mid = (begin+end) >> 1; if(key == arr[mid]) begin = mid+1; //注意点1 else if(key < arr[mid]) end = mid; else if(key > arr[mid]) begin = mid+1; } return arr[begin-1] == key ? (begin-1) : -1; //注意点2 }
注意点:
begin = mid+1
,向右缩小搜索范围,查找中间元素右边是否有相同的元素begin-1
,因为注意点1中令begin = mid+1
,所以最后跳出循环时begin指向目标元素右边一位参考:
① https://blog.csdn.net/u012194956/article/details/79103843
② https://www.cnblogs.com/kyoner/p/11080078.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。