算法 二分查找法

二分查找法

  • 二分查找法
  • 二分查找法是一种算法,其输入为有序的元素列表。
  • 原理
  • 下面我们通过一个例子来了解下二分查找法的原理

例题:设计一个函数,接收一个有序数组和一个元素,如果指定的元素包含在数组中,则返回其位置。

看见这道题,我们正常的想法为遍历数组的所有元素然后一个一个的与数值相比较,如果相等,返回索引,如果在循环执行完后没有退出函数的话,就返回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次。具体请看下表

简单查找执行次数
1010
100100
40亿40亿
二分查找执行次数
104
1007
40亿32

看到区别了吗,随着元素个数的增加,二分查找需要的额外时间并不多,而简单查找需要的额外时间很多。用大O表示法来表示的话,简单查找的运行时间为O(n),而二分查找的运行时间为O(log n)

大O表示法指出的是最糟糕情况下的运行时间

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值