地球人都知道“二分查找”,方法也非常简单,但是你能不能在10分钟内写出一个没有bug的程序呢?

知易行难,自己动手写一下试一试吧。

public class BinarySearch {
    public static int search(int [] A,int target,int a, int b)
    {
        int  middle = (a+b)/2;
        if(a>b)
            return -1;
        else if (A[middle]==target)
            return middle;
        else if (A[middle]< target)
            return search(A,target,middle+1,b);
        else
            return search(A,target,a,middle-1);
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int A [] = {2,4,6,8,10};
        System.out.println( BinarySearch.search(A,1 , 0, A.length-1)  );
        System.out.println( BinarySearch.search(A,2 , 0, A.length-1)  );
        System.out.println( BinarySearch.search(A,3 , 0, A.length-1)  );
        System.out.println( BinarySearch.search(A,4 , 0, A.length-1)  );
        System.out.println( BinarySearch.search(A,5 , 0, A.length-1)  );
        System.out.println( BinarySearch.search(A,6 , 0, A.length-1)  );
        System.out.println( BinarySearch.search(A,7 , 0, A.length-1)  );
        System.out.println( BinarySearch.search(A,8 , 0, A.length-1)  );
        System.out.println( BinarySearch.search(A,9 , 0, A.length-1)  );
        System.out.println( BinarySearch.search(A,10 , 0, A.length-1) );
        System.out.println( BinarySearch.search(A,11 , 0, A.length-1) );
    }
}

上面的代码看似是没有任何问题了,但是呢,其实还是有一个很微妙的bug,这个bug发生在:

int  middle = (a+b)/2;

这一行。想一下,如果a+b超出了Int型的最大值了呢???所以呢,修正这个bug应该这样:
public class BinarySearch {
    public static int search(int [] A,int target,int a, int b)
    {
        int  middle = a+(b-a)/2;
        if(a>b)
            return -1;
        else if (A[middle]==target)
            return middle;
        else if (A[middle]< target)
            return search(A,target,middle+1,b);
        else
            return search(A,target,a,middle-1);
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int A [] = {2,4,6,8,10};
        System.out.println( BinarySearch.search(A,1 , 0, A.length-1)  );
        System.out.println( BinarySearch.search(A,2 , 0, A.length-1)  );
        System.out.println( BinarySearch.search(A,3 , 0, A.length-1)  );
        System.out.println( BinarySearch.search(A,4 , 0, A.length-1)  );
        System.out.println( BinarySearch.search(A,5 , 0, A.length-1)  );
        System.out.println( BinarySearch.search(A,6 , 0, A.length-1)  );
        System.out.println( BinarySearch.search(A,7 , 0, A.length-1)  );
        System.out.println( BinarySearch.search(A,8 , 0, A.length-1)  );
        System.out.println( BinarySearch.search(A,9 , 0, A.length-1)  );
        System.out.println( BinarySearch.search(A,10 , 0, A.length-1) );
        System.out.println( BinarySearch.search(A,11 , 0, A.length-1) );
    }
}

查找一个元素是否存在,自然分为“存在”和“不存在”两种情况。在思考二分查找的时候,先思考“存在”的情况,设计算法,然后再去考虑“不存在”的情况。

如果同时思考“存在”和“不存在”两种情况,那么很容易被绕晕。

《算法导论》习题2.3-5 二分搜索 Binary Search的更多相关文章

  1. 【LeetCode-面试算法经典-Java实现】【096-Unique Binary Search Trees(唯一二叉搜索树)】

    [096-Unique Binary Search Trees(唯一二叉搜索树)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Given n, how many s ...

  2. 数据结构与算法--二分搜索(binary search)

    前言 之前面试准备秋招,重新翻起了<编程之美>.在第三章节看到了一道关于二分搜索的讨论,觉得有许多细节是自己之前也没怎么特别注意地方,比如二分搜索的初始条件,转化.终止条件之类的. 问题 ...

  3. LeetCode算法题-Lowest Common Ancestor of a Binary Search Tree

    这是悦乐书的第197次更新,第203篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第59题(顺位题号是235).给定二叉搜索树(BST),找到BST中两个给定节点的最低共 ...

  4. 二分搜索 - Binary Search

    二分搜索是一种在有序数组中寻找目标值的经典方法,也就是说使用前提是『有序数组』.非常简单的题中『有序』特征非常明显,但更多时候可能需要我们自己去构造『有序数组』.下面我们从最基本的二分搜索开始逐步深入 ...

  5. 算法学习记录-查找——折半查找(Binary Search)

    以前有个游戏,一方写一个数字,另一方猜这个数字.比如0-100内一个数字,看谁猜中用的次数少. 这个里面用折半思想猜会大大减少次数. 步骤:(加入数字为9) 1.因为数字的范围是0-100,所以第一次 ...

  6. 《算法导论》习题2.3-6 改进的InsertSort

    InsertSort中有关键的一步是把当前元素A[i]插入到已经排好序的A[1,i-1]的合适的位置上,在原始的InsertSort算法中, 采用的是从后往前一步一步查找的方法,习题2.3-6要求利用 ...

  7. [置顶] 《算法导论》习题解答搬运&&学习笔记 索引目录

    开始学习<算法导论>了,虽然是本大部头,可能很难一下子看完,我还是会慢慢地研究的. 课后的习题和思考有些是很有挑战性的题目,我等蒻菜很难独立解决. 然后发现了Google上有挺全的algo ...

  8. (搬运)《算法导论》习题解答 Chapter 22.1-1(入度和出度)

    (搬运)<算法导论>习题解答 Chapter 22.1-1(入度和出度) 思路:遍历邻接列表即可; 伪代码: for u 属于 Vertex for v属于 Adj[u] outdegre ...

  9. 算法导论课后习题解答 第一部分 练习1.1-1->1.1-5

    很高兴能和大家一起共同学习算法导论这本书.笔者将在业余时间把算法导论后面的题解以博文的形式展现出来希望能得到大家的支持谢谢.如果有可能我会做一些教学视频免费的供大家观看. 练习题选自算法导论中文第三版 ...

随机推荐

  1. sql trim()函数去掉两头空格

    1.sql trim()函数去掉两头空格 sql语法中没有直接去除两头空格的函数,但有ltrim()去除左空格rtrim()去除右空格. 合起来用就是sql的trim()函数,即select ltri ...

  2. Android :android.os.Process.myTid()与 Thread.currentThread().getId();

    这两种方式得到的ID并不是相同的,前者的返回值是int,后者是long. 个人猜测:应该是一个线程的两种得到的方式.类似于一个人有2个名字. 如有不对,请指正!

  3. dl以及dt,dd,以及table的tr,th,td最清楚分析

    1,定义:<dl> <dt> <dd>是一组合标签,使用了dt dd最外层就必须使用dl包裹,此组合标签我们也又叫表格标签,与table表格类似组合标签,故名我们也 ...

  4. 浅谈C# 多态的魅力(虚方法,抽象,接口实现)

    前言:我们都知道面向对象的三大特性:封装,继承,多态.封装和继承对于初学者而言比较好理解,但要理解多态,尤其是深入理解,初学者往往存在有很多困惑,为什么这样就可以?有时候感觉很不可思议,由此,面向对象 ...

  5. RMQ 详解

    RMQ(Range Minimum/Maximum Query)问题:RMQ问题是给定一个区间,求这个区间中的最大或最小值的问题 RMQ采用动态规划的思想来求解:(st算法:Square Table) ...

  6. eclipse Dynamic web project 工程目录

    如图,我创建了一个work 的web project,当工程完成之后,部署在服务器上时,整个work工程会被打包成一个war包,如 除了可以在eclipse上运行,工具会帮我们自动部署在服务器上之外, ...

  7. 更换arm-linux-gcc 4.3.2编译器

    先创建一个临时目录:mcx@mcx-virtual-machine:/home/work/tools$ mkdir tmp 解压到根目录:mcx@mcx-virtual-machine:/home/w ...

  8. AS3条件编译

    package { import flash.display.Sprite; public class Main extends Sprite { public function Main() { s ...

  9. 动态规划3-------poj1050

    首先还是对题目的意思进行说明,给出一个矩阵的数,然后求出一个子矩阵这个子矩阵包含的数的和是最大的.   首先对于题目进行转化,利用一个数组add进行存放临时数据,第一行存放原来数据的第一行,第二行存放 ...

  10. Centos下安装jdk详解

    环境: 系统: [root@Wulaoer ~]# cat /proc/version Linux version 2.6.32-431.el6.x86_64 (mockbuild@c6b8.bsys ...