前言科普

第一篇二分搜索论文是 1946 年发表,然而第一个没有 bug 的二分查找法却是在 1962 年才出现,中间用了 16 年的时间。

2019 年的你,在面试的过程中能手写出没有 bug 的二分查找法么?

定义

在计算机科学中,二分查找(英语:binary search),也称折半搜索(英语:half-interval search)、对数搜索(英语:logarithmic search),是一种在有序数组中查找某一特定元素的搜索算法

搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;

如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。

如果在某一步骤数组为空,则代表找不到。

这种搜索算法每一次比较都使搜索范围缩小一半。

二分查找法代码

按照上面的定义,我们来尝试写一下二分查找法的代码。

public static int binary(int[] arr, int data) {
        int min = 0;
        int max = arr.length - 1;
        int mid;
        while (min <= max) {
            mid = (min + max) / 2;
            if (arr[mid] > data) {
                max = mid - 1;
            } else if (arr[mid] < data) {
                min = mid + 1;
            } else {
                return mid;
            }
        }
        return -1;
    }

现在问你,上面的代码有没有问题?哪段代码会出现 bug ?

请思考一分钟后再往下查看。

对于上面这段代码而言,问题出在第 6 行代码处:

mid = (min + max) / 2;

这句代码在 min 和 max 很大的时候,会出现溢出的情况,从而导致数组访问出错。

别看现在轻描淡写的指出了这个错误,但这个错误在当时可是存在了好些年。

那怎么改进呢?一般的做法是这样的:将加法变成减法。

public static int binary(int[] arr, int data) {
        int min = 0;
        int max = arr.length - 1;
        int mid;
        while (min <= max) {
            // 防止溢出
            mid =  min + (max - min) / 2;
            if (arr[mid] > data) {
                max = mid - 1;
            } else if (arr[mid] < data) {
                min = mid + 1;
            } else {
                return mid;
            }
        }
        return -1;
    }

还有一种更高逼格的写法,也是官方的二分搜索法的实现写法:使用 位运算

 public static int binary(int[] arr, int data) {
        int min = 0;
        int max = arr.length - 1;
        int mid;
        while (min <= max) {
            // 无符号位运算符的优先级较低,先括起来
            mid =  min + ((max - min) >>> 1);
            if (arr[mid] > data) {
                max = mid - 1;
            } else if (arr[mid] < data) {
                min = mid + 1;
            } else {
                return mid;
            }
        }
        return -1;
    }

希望通过今天的文章能帮助读者们在面试中手写对代码,毕竟,对于很多小公司来说,二分查找法会出现在他们的笔试题中的。

面试官,我会写二分查找法!对,没有 bug 的那种!的更多相关文章

  1. 二分查找法 java

    前几天去面试,让我写二分查找法,真是哔了狗! 提了离职申请,没事写写吧! 首先二分查找是在一堆有序的序列中找到指定的结果. public class Erfen { public static int ...

  2. 用c语言编写二分查找法

    二分法的适用范围为有序数列,这方面很有局限性. #include<stdio.h> //二分查找法 void binary_search(int a[],int start,int mid ...

  3. python 全栈开发,Day15(递归函数,二分查找法)

    一.递归函数 江湖上流传这这样一句话叫做:人理解循环,神理解递归.所以你可别小看了递归函数,很多人被拦在大神的门槛外这么多年,就是因为没能领悟递归的真谛. 递归函数:在一个函数里执行再调用这个函数本身 ...

  4. 二分查找法(java版)

    二分查找法也称为折半查找法,在有序的序列中使用二分法可以提高程序的执行效率. 典型的二分查找法代码 public int binarySearch1(int[] arr,int target){ in ...

  5. 二分查找法&大O表示法

    二分查找法的输入是一个有序的元素列表,如果要查找的元素包含在列表中,二分查找返回其位置,否则返回null Python代码(来源于<算法图解>一书): def binary_search( ...

  6. jvascript 顺序查找和二分查找法

    第一种:顺序查找法 中心思想:和数组中的值逐个比对! /* * 参数说明: * array:传入数组 * findVal:传入需要查找的数 */ function Orderseach(array,f ...

  7. java for循环和数组--冒泡排序、二分查找法

    //100以内与7相关的数   for(int a=1;a<=100;a++){    if(a%7==0||a%10==7||a/10==7){     System.out.print(a+ ...

  8. 学习练习 java 二分查找法

    package com.hanqi; import java.util.*; public class Test5 { public static void main(String[] args) { ...

  9. Java-数据结构与算法-二分查找法

    1.二分查找法思路:不断缩小范围,直到low <= high 2.代码: package Test; import java.util.Arrays; public class BinarySe ...

随机推荐

  1. Drawable.SetDither(Boolean) Method

    https://docs.microsoft.com/zh-cn/dotnet/api/android.graphics.drawables.drawable.setdither?view=xamar ...

  2. ES6 ES7 ES8 相关用法

    set Set作为ES6新的数据解构(类数组),它的成员都是唯一的,因为最直接的使用场景便是去重.并.差.交集的使用.它使用的算法叫做“Same-value-zero equality”,类似精确运算 ...

  3. jQuery-文件上传问题解决

    后端要求文件上传需传参数为二进制流,用form-data方式传递,如下图所示: 为了满足该输入参数要求,上传代码如下: <input type="file" id=" ...

  4. Python实战——基于股票的金融数据量化分析

    说明:本文只是通过自己的已学知识对股票数据进行了一个简单的量化分析,只考虑了收盘情况,真实的量化交易中仅仅考虑收盘情况是不够的,还有很多的复杂因素,而且仅仅三年数据是不足以来指导真实的股票交易的,因此 ...

  5. C - Train Problem II——卡特兰数

    题目链接_HDU-1023 题目 As we all know the Train Problem I, the boss of the Ignatius Train Station want to ...

  6. PHP+jQuery开发简单的翻牌抽奖实例

    PHP+jQuery开发简单的翻牌抽奖实例,实现流程:页面放置6个方块作为奖项,当抽奖者点击某一块时,方块翻转到背面,显示中奖信息,这个奖品是随机的,不是固定的. 在页面上放置6个奖项: <ul ...

  7. spring一个标准的xml文件头

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  8. iOS引导页(镂空效果)

    推荐使用SDK:pod 'EAFeatureGuideView' 温馨提示:(引导的图片图标需要私人订制的可以用自己的,让UI提供) 参考链接:https://www.jianshu.com/p/c9 ...

  9. iOS11自定义tabBar重影问题

    转载自:(主链接)https://www.jianshu.com/p/1be90349fdb4 https://www.cnblogs.com/coderYu/p/5859638.html 很实用,有 ...

  10. Android进阶之绘制-自定义View完全掌握(二)

    这是自定义View系列的第二篇博客,我们继续来学习关于自定义View的知识. 今天我们来实现一下广告条案例. 我们要实现的是这样的一个效果. 要想实现这样的效果,我们可以借助ViewPager控件,然 ...