[图解算法]-二分查找

663 阅读2分钟

前言

算法是一组完成任务的的指令

(大概就是,你今天要上班,但是你还要买杯咖啡。算法:出门->星巴克->公司)

二分查找

二分查找其实是我们生活中经常用到的逻辑。

比如你的小姐妹买了件200元以内的衣服,让你猜价格。我们不会从1元开始往上猜,为了猜的次数最少,我们会从中间的数字100开始猜。

我:“100元”

姐妹:“没那么贵”

我:“(此时100元-200元的数字都能排除,再取中间值50)50元”

姐妹:“没那么便宜”

我:“(取50-100之间的数字)75”

姐妹:“对了”

嗯,恭喜你学会了第一种算法,这就是二分查找

(二分查找每次都能排除一半的数字,仅当列表是有序时,才能使用二分查找)

公式:待查找项有n个时,我们最多要查找次。

这里补充一下,log是对数,对数是幂的逆运算。log2(n)的意思是:多少个2相乘的结果是n。那么,log10(100)得出的结果是2。10*10=2(2个10相乘的结果为100)。

那么在数组中,我们从0开始编号,设定

备选数组的第一位是low,备选数组的最后一位为high。备选数组最中间的元素为mid

low = 0;

high = length(arr) -1;

那么中间的元素就为:mid = (low + high) / 2;

设定item为我们想要猜到的正确数字,那么我们从数组中间开始猜

key = arr[mid];

if (key < item) {

low = mid +1; //此时我们就把数组中一半的元素都砍掉了,也就是mid前面的数字我们全都拿掉了

}
js完整代码:

const arr = [1, 3, 5, 7, 9];

function binarySearch(arr, key) {
    let low = 0;                  // 实时定义备选项数组的第一个索引
    let high = arr.length - 1;    // 实时定义备选项数组的最后一个索引

    while (low <= high) {         // 边缘数字索引值会变,判断左边的索引是不是小于等于右边的索引,以此判断里面是否至少有一个值
        let mid = parseInt((high + low) / 2);
        if (arr[mid] == key) { 
            return mid;           // 最终返回的值 是正确数字的索引
        } else if (key < arr[mid]) {
            high = mid - 1;                 
        } else if (key > arr[mid]) {
            low = mid + 1;    
        } 
    };
    return -1;
}

binarySearch(arr, 1);  

配了一个精致的解释图(#^.^#) 同居的妹妹都夸我这图好精致。

程序的运行时间

优质的代码都是选择了效率最高的算法,最大限度地减少运行时间占用空间

比如我们的数组里有100个数字,用简单查找法(逐个查找)需要猜测100次,简单查找法的次数和列表长度相同。简单查找法的次数(运行时间)叫做线性时间(linear time),表示为O(n)。

而利用二分查找法,100个数字,我们只需要猜7次(或8次)。二分查找法的次数(运行时间)叫做对数时间(英文名不知道是不是叫log time),表示为O(log n)。

参考资料

1. 算法图解 [Aditya Bhargava]