彻底弄懂二分法

在一个1到100的列表中,如何最快找到目标数字,如果按照普通方法遍历,将所有数字都拿出来一一对比,那么最多需要100步。

而二分法每次都会从中间找起,每次都可以排除一半的数字,这样一来会大大减少对比次数,在100以内找到目标数只需要七步。

所以,二分法的关键在于如何找出中间数,100的中间数当然很好找,直接除2就行,但是如果目标数大于50,那么如何在50到100之间找出中间数?

首先我们要设置三个变量来表示1-100的答案范围,分别为:

//list为从1到100的列表
var mid = list.length/2
var low = 1
var high = 100

如果目标数大于50,那么应该将答案范围收缩至50-100,这时候就会发现,如果目标数大于中间数(answer > mid),就只有low的值改变。
那么反过来说,如果目标数小于中间数(answer < mid),那就只有high的值改变,因此判断代码应该是这样:

if(answer > mid){
	low = mid
	...
} else if(answer < mid){
	high = mid
	...
}

接下来只要找出中间数就行了,要解决这个问题其实也很简单,首先要让它们保持对称,也就是说原来是这样:

1–50–mid–100

要把它们改成这样:

1–50–mid–100–150

这样一来,除以2就能找出中间数,因此公式为:

(high+low)/2

完整代码:

//创建一个1-100的数组
const list = function(){
    var list = []
    for (let i = 1; i < 101; i++) {
        list.push(i)
    }
    return list
}

//二分法
const dichotomy = function(answer, list){
    var mid = list.length / 2
    var low = 0
    var hig = 100
    //计数器,计算花了多少步
    var count = 0
    while(true){
        if (answer > mid){
            low = mid + 1
            //Math.round可以将小数点去除
            mid = Math.round((hig+low)/2)
            count += 1
        } else if(answer < mid){
            hig = mid - 1
            mid = Math.round((hig+low)/2)
            count += 1
        }else{
        	console.log(`共花了${count}步`}
            console.log(answer+'='+mid)
            return mid
        }
    }
}

var lists = list()
dichotomy(49,lists)

你可能感兴趣的:(算法)