这是我参与「掘金日新计划 · 8 月更文挑战」的第30天,点击查看活动详情
分不清东南西北,只知道梦想是远方 —— 我是小晨,今天来聊一下二分查找
什么是二分查找?
在计算机科学领域,二分查找(Binary Search) 是一种查找算法(也称折半查找),用来在一个数组中查找指定的元素。注意这个数组需要是一个有序数组才有效。二分查找优于标准的线性查找(Linear Search),因为它查找速度更快,效率更高。
这种算法不是在一个for循环中依次按照索引0,1,2,3,4这样查找,它的具体做法是每次把查找范围缩小一半,直到找到目标值。
速度快
- 如果是普通遍历,查找100个规模,最坏情况需要 100 次.
- 经过二分查找,最坏只需要 7 次.
100个元素-->50-->25-->13-->7-->4-->2-->1
- 速度大大提升, ok 直接上题:
原题链接:二分查找来源力扣(LeetCode)
/*给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target
*写一个函数搜索 nums 中的 target
*如果目标值存在返回下标,否则返回 -1。
*/
//题目 二分查找
/**
* @param {number[]} nums: [-1,0,3,5,9,12]
* @param {number} target: 3
* @return {number}
*/
var search = function(nums, target) {
};
过程解析
解析过程中以下面代码为例:
let arr = [1, 2, 3, 6, 4, 8, 9, 10]
-
在执行查找操作时需要把3个数据保存为变量:
minText,len和maxText。minText初始值为0 -
MaxText的值可以由数组的长度计算得到:let maxIndex = nums.length - 1; -
我们用
minText和MaxText的值相加,然后除以 2 可以得到len的初始值。 -
问题是这个值可能不是一个整数,可以用
Math.floor()或者Math.ceil()或者parseInt()来得到临近的整数,这里我们用parseInt():let len = parseInt((MaxText + minText) / 2)。我们的while循环会一直运行直到结束。这里可以用while(minText <= maxText) -
比如数组里一共有
9个元素,根据上述的计算规则。len = parseInt(( 0 + 8) / 2),得到值为4。我们选取数组中索引为4的元素4,。现在我们会用这个值和目标值“8”进行比较,看看它更大还是更小。如果len所在的值比目标值8小,我们知道目标值可能存在于len的右侧。然后把len的值调整为len右侧的那个索引。 -
如果
len所在的值大于目标值8,我们知道目标值可能存在于len的左侧。然后把maxText调整为len左侧的那个索引。如果len所在的值恰好等于目标值8,那么我们就顺利找到了目标值,把这个len值返回即可。这个while循环可能只会执行一次,也有可能会执行很多次,取决于这个数组的长度。最后如果没有找到目标值,我们返回 -1 表示没有找到指定的值。
我们会在数组中间的元素作为
len元素,然后把它的值和目标值进行比对。根据目标值是大于还是小于len元素,我们可以从数组中排除左侧或者右侧的元素。
/*给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target
*写一个函数搜索 nums 中的 target
*如果目标值存在返回下标,否则返回 -1。
*/
//题目 二分查找
/**
* @param {number[]} nums: [-1,0,3,5,9,12]
* @param {number} target: 3
* @return {number}
*/
var search = function (nums, target) {
if (!nums.length) {
return -1;
}
let minText = 0, maxText = nums.length - 1, len;
while (minText < maxText) {
len = minText + Math.floor((maxText - minText) / 2);
if (nums[len] == target) {
return len;
} else if (nums[len] < target) {
minText = len + 1;
} else if (nums[len] > target) {
maxText = len - 1;
}
}
return nums[minText] == target ? minText : -1;
};
最后
我是小晨,一个不想加班的加班族。