算法基础——二分法查找

   日期:2020-08-21     浏览:81    评论:0    
核心提示:场景????假设有这样一个“猜数字”的游戏:裁判在1~100之间想一个数字,我们报数字来猜裁判心中所想的数字,裁判能提示我们所猜的这个数字是“大了”,“小了”,或者“猜对啦!”,直到裁判说“猜对啦”,这个游戏才算结束!方案一最直接的一个办法就是,我们可以有序的从1报到100,代码实现如下:// 用随机数来模拟裁判心中所想的数字(1~100)let num = Math.floor(Math.random() * 100 + 1)console.log(`裁判心中想的数字是${num}`)//

场景

假设有这样一个“猜数字”的游戏:裁判在1~100之间想一个数字,我们报数字来猜裁判心中所想的数字,裁判能提示我们所猜的这个数字是“大了”,“小了”,或者“猜对啦!”,直到裁判说“猜对啦”,这个游戏才算结束!

方案一

最直接的一个办法就是,我们可以有序的从1报到100,代码实现如下:

// 用随机数来模拟裁判心中所想的数字(1~100)
let num = Math.floor(Math.random() * 100 + 1)
console.log(`裁判心中想的数字是${num}`)
// for循环模拟我们猜的过程
for(let i = 1; i <= 100; i++) {
    if(i < num){
        console.log('小了')
    } else if(i === num){
        console.log(`猜中啦!这个数字是${i}`)
        console.log(`一共猜了${i}次`)
        break
    }
}

猜想

以上确实是不失为一种方案,但可以看出,这种方案最少需要猜测1次,最多需要猜测100次。想一想,有没有一种方法,能够让我们尽可能少的猜测就能猜到这个数字。假如我们从中间开始猜,每次都能排除掉一半的数字,然后继续在剩下的数字中取中间值,这样又能排除掉一半…重复这个动作,直到找到正确的数字,这便是二分查找算法了。并且我们还有一个“大了”的条件我们还没有用上,如果用这种方式,那么这个条件就能用上了。

方案二

每次我们从最中间的数开始猜,如果有小数点(1~100最中间的数是50.5)就进行向下取整。

// 还是用随机数来模拟裁判心中所想的数字(1~100)
let num = Math.floor(Math.random() * 100 + 1)
console.log(`裁判心中想的数字是${num}`)
// 定义(0~100)这个区间的小值lit,最大值big,和中间值mid,i用来记录循环的次数
let lit = 0, big = 100, mid = Math.floor((lit + big) / 2), i = 0
// 只要范围没有缩小到只剩一个元素,就循环
while(lit <= big) {
    i++ 
    mid = Math.floor((lit + big) / 2)
    // 如果中间值比num小,则把mid+1赋给lit
    if(mid < num) {
        console.log('小了')
        lit = mid + 1
    } else if(mid > num) { // 如果中间值比num大,则把mid-1赋给big
        console.log('大了')
        big = mid - 1
    } else { // 如果相等,则打印mid和循环次数,并跳出循环
        console.log(`猜对啦!这个数字是${mid}`)
        console.log(`一共猜了${i}次`)
        break
    }
}

结论

方案一,最多需要猜测100次,而方案二最多只需要7次,可见二分查找的效率比普通循环的要高很多。一般对于包含了n个元素的有序列表来说,二分查找最多只需要 l o g 2 n {log_2{n}} log2n次就能找到。

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服