版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
二分查找法
- 二分查找法
- 二分查找法是一种算法,其输入为有序的元素列表。
- 原理
- 下面我们通过一个例子来了解下二分查找法的原理
例题:设计一个函数,接收一个有序数组和一个元素,如果指定的元素包含在数组中,则返回其位置。
看见这道题,我们正常的想法为遍历数组的所有元素然后一个一个的与数值相比较,如果相等,返回索引,如果在循环执行完后没有退出函数的话,就返回false。
代码为
var count=0;//计数
function lookUp(arra, a) {//arra为数组 a为元素
for (var i = 0; i < arra.length; i++) {//遍历数组中的所有元素
count++; //计数 代码执行一次 次数加1
if (arra[i] === a) { //判断 存在返回索引
return i;
}
}
return false;//不存在 返回false
}
console.log(lookUp([1, 2, 3, 4, 5, 6, 7, 8, 9], 9));
console.log('代码执行的次数为'+count);
执行结果如下
上面的查找方法为简单查找,如果在最糟糕的情况下,即元素在最后一个,那么9个数你要执行9次,100个数你要执行100次,10亿个数要执行10亿次。假设代码执行一次需要1s,10亿次,就是10亿秒,效率极其低下。
那么下面我们介绍一个更佳的查找方式,即二分查找法。
二分查找法,顾名思义,二分即一分为二,假设有100个数,我们先找到索引为50的元素,然后与要找的元素做比较,如果它大于索引为50的元素,那么我们就排除了索引为50前面的元素,因为我们是一个有序数组,然后我们在找索引为75的元素进行判断,因为75为50到100中间的数,然后以此类推。
代码为
var count=0;//计数
function lookUp(arra, x) {//arra为数组 a为元素
for (var start = 0, end = arra.length - 1; start <= end;) {//只要范围没缩小到最后一个元素
count++;//记录执行次数
var middle = (start + end) / 2;//找到中间数
middle = Math.floor(middle); //如果为奇数,需要向下取整
if (arra[middle] === x) {//判断返回下标
return middle;
}
if (arra[middle] < x) {//小于的话 排除中间数以及前面的数
start = middle + 1;
}
if (arra[middle] > x) {//大于的话 排除中间数以及后面的数
end = middle - 1;
}
}
return false;
}
console.log(lookUp([1, 2, 3, 4, 5, 6, 7, 8, 9], 9));
console.log('代码执行的次数为' + count);
执行结果如下
执行结果图示
根据结果可以看出同样的9个数简单查找需要9次,但二分查找只需要4次,不要以为只少了5次。具体请看下表
简单查找 | 执行次数 |
---|---|
100 | 10 |
100 | 100 |
40亿 | 10亿 |
二分查找 | 执行次数 |
---|---|
10 | 4 |
100 | 7 |
40亿 | 32 |
看到区别了吗,随着元素个数的增加,二分查找需要的额外时间并不多,而简单查找需要的额外时间很多。用大O表示法来表示的话,简答查找的运行时间为O(n),而二分查找的运行时间为O(log n)
扫描二维码关注公众号,回复: 7659251 查看本文章
大O表示法指出的是最糟糕情况下的运行时间