BinarySearch(前端实现二分查找算法,也称折半搜索算法)
前端  /  管理员 发布于 8年前   511
在计算机科学中,二分查找算法,也称折半搜索算法,是一种在有序数组中查找某一特定元素的搜索算法
想要应用二分查找法,则这一堆数应有如下特性:
搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束
如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较
如果在某一步骤数组为空,则代表找不到
这种搜索算法每一次比较都使搜索范围缩小一半
如下图所示:
相比普通的顺序查找,除了数据量很少的情况下,二分查找会比顺序查找更快,区别如下所示:
基于二分查找的实现,如果数据是有序的,并且不存在重复项,实现代码如下:
function BinarySearch(arr, target) {
if (arr.length <= 1) return -1
// 低位下标
let lowIndex = 0
// 高位下标
let highIndex = arr.length - 1
while (lowIndex <= highIndex) {
// 中间下标
const midIndex = Math.floor((lowIndex + highIndex) / 2)
if (target < arr[midIndex]) {
highIndex = midIndex - 1
} else if (target > arr[midIndex]) {
lowIndex = midIndex + 1
} else {
// target === arr[midIndex]
return midIndex
}
}
return -1
}
如果数组中存在重复项,而我们需要找出第一个制定的值,实现则如下:
function BinarySearchFirst(arr, target) {
if (arr.length <= 1) return -1
// 低位下标
let lowIndex = 0
// 高位下标
let highIndex = arr.length - 1
while (lowIndex <= highIndex) {
// 中间下标
const midIndex = Math.floor((lowIndex + highIndex) / 2)
if (target < arr[midIndex]) {
highIndex = midIndex - 1
} else if (target > arr[midIndex]) {
lowIndex = midIndex + 1
} else {
// 当 target 与 arr[midIndex] 相等的时候,如果 midIndex 为0或者前一个数比 target 小那么就找到了第一个等于给定值的元素,直接返回
if (midIndex === 0 || arr[midIndex - 1] < target) return midIndex
// 否则高位下标为中间下标减1,继续查找
highIndex = midIndex - 1
}
}
return -1
}
实际上,除了有序的数组可以使用,还有一种特殊的数组可以应用,那就是轮转后的有序数组
有序数组即一个有序数字以某一个数为轴,将其之前的所有数都轮转到数组的末尾所得
例如,[4, 5, 6, 7, 0, 1, 2]就是一个轮转后的有序数组
该数组的特性是存在一个分界点用来分界两个有序数组,如下:
分界点有如下特性:
代码实现如下:
function search (nums, target) {
// 如果为空或者是空数组的情况
if (nums == null || !nums.length) {
return -1;
}
// 搜索区间是前闭后闭
let begin = 0,
end = nums.length - 1;
while (begin <= end) {
// 下面这样写是考虑大数情况下避免溢出
let mid = begin + ((end - begin) >> 1);
if (nums[mid] == target) {
return mid;
}
// 如果左边是有序的
if (nums[begin] <= nums[mid]) {
//同时target在[ nums[begin],nums[mid] ]中,那么就在这段有序区间查找
if (nums[begin] <= target && target <= nums[mid]) {
end = mid - 1;
} else {
//否则去反方向查找
begin = mid + 1;
}
//如果右侧是有序的
} else {
//同时target在[ nums[mid],nums[end] ]中,那么就在这段有序区间查找
if (nums[mid] <= target && target <= nums[end]) {
begin = mid + 1;
} else {
end = mid - 1;
}
}
}
return -1;
};
对比普通的二分查找法,为了确定目标数会落在二分后的哪个部分,我们需要更多的判定条件
二分查找法的O(logn)
让它成为十分高效的算法。不过它的缺陷却也是比较明显,就在它的限定之上:
关于二分查找的应用场景,主要如下:
123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..路人 在
php中使用hyperf框架调用讯飞星火大模型实现国内版chatgpt功能示例中评论 教程很详细,如果加个前端chatgpt对话页面就完美了..
Copyright·© 2019 侯体宗版权所有·
粤ICP备20027696号