`

二分查找算法小结

 
阅读更多
在做leetcode二分查找类型题目时写while条件总担心写错,也确实好几次都是得到Wrong Answer之后再修改对的。在做Search for a range一题时,虽然被Accept了,但看网上其他同学的解析并不是特别理解,终于下决心去好好研究下最经典的二分查找算法,搞清楚不同情况下为什么while条件写法不一样。很幸运,很快便找到一遍总结得很棒的博客:
http://blog.csdn.net/daniel_ustc/article/details/17307937
拜读后自己实现了下,实现过程中对while条件不同情况下为什么不一样理解得更深刻了。

实现的三个二分查找方法分别解决如下问题:
1)查找数组中target出现的下标,不存在返回-1
2)查找数组中target第一次出现的下标位置,若不存在返回-1
3)查找数组中target最后一次出现的下标位置,若不存在返回-1
PS: 数组升序排列,可能有重复元素
package org.work.basic.binarysearch;

import junit.framework.Assert;
import org.junit.Test;

public class BinarySearchCore {

    @Test 
    public void testBinarySearch() {
        int[] nums = {0,1,1,1,2};
        Assert.assertEquals(2, binarySearch(nums, 1));
        Assert.assertEquals(1, binarySearchFirst(nums, 1));
        Assert.assertEquals(3, binarySearchLast(nums, 1));
        int[] nums1 = {1};
        Assert.assertEquals(0, binarySearch(nums1, 1));
        Assert.assertEquals(0, binarySearchFirst(nums1, 1));
        Assert.assertEquals(0, binarySearchLast(nums1, 1));
        int[] nums2 = {1,1};
        Assert.assertEquals(0, binarySearch(nums2, 1));
        Assert.assertEquals(0, binarySearchFirst(nums2, 1));
        Assert.assertEquals(1, binarySearchLast(nums2, 1));
        
    }
    // 查找target在nums[]中的下标,若有重复,返回任意一个即可,若找不到返回 -1
    public int binarySearch(int[] nums, int target) {
        if (nums == null || nums.length == 0)
            return -1;
        int left = 0, right = nums.length - 1;
        int mid = 0;
        while (left <= right) {
            mid = left + ((right - left) >> 1);
            if (target == nums[mid])
                return mid;
            else if (target < nums[mid])
                right = mid - 1;
            else 
                left = mid + 1;
        }
        return -1;
    }
    // 查找target在nums[]中第一次出现的下标,若找不到返回-1
    public int binarySearchFirst(int[] nums, int target) {
        if (nums == null || nums.length == 0)
            return -1;
        int left = 0, right = nums.length - 1;
        int mid = 0;
        while (left < right) { // 此处不能有等号,否则可能在right=mid处死循环,考虑case:[1], 1
            mid = left + ((right - left) >> 1);
            if (target > nums[mid])
                left = mid + 1;
            else
                right = mid;
        }
        if (nums[left] == target)
            return left;
        return -1;
    }
    // 查找target在nums[]中最后一次出现的下标,若找不到返回-1
    public int binarySearchLast(int[] nums, int target) {
        if (nums == null || nums.length == 0)
            return -1;
        int left = 0, right = nums.length - 1;
        int mid = 0;
        while (left + 1 < right) { // 循环只处理元素个数大于两个的情况,两个以下元素时可能在left=mid处死循环(两个元素时left==mid),考虑case:[1,1],1
            mid = left + ((right - left) >> 1);
            if (target < nums[mid])
                right = mid - 1;
            else
                left = mid;
        }
        if (nums[right] == target)
            return right;
        else if(nums[left] == target)
            return left;
        return -1;
    }
}

分享到:
评论

相关推荐

    查找算法和排序算法小结

    包括顺序查找、二分查找、选择排序、冒泡排序,二分排序,插入排序,希尔排序,堆排序,归并排序等

    Delphi算法与数据结构 源码(上)

    这本书强调了查找算法(如顺序和二分查找),另外也重点介绍了排序算法(包括冒泡排序、插入排序、希尔排序、快速排序和堆排序),此外还提供了有关的优化技术。不仅如此,作者还介绍了散列和散列表、优先队列、状态...

    Delphi算法与数据结构 源码(下)

    这本书强调了查找算法(如顺序和二分查找),另外也重点介绍了排序算法(包括冒泡排序、插入排序、希尔排序、快速排序和堆排序),此外还提供了有关的优化技术。不仅如此,作者还介绍了散列和散列表、优先队列、状态...

    java数据结构与算法第二版

    递归的二分查找 汉诺(Hanoi)塔问题 归并排序 消除递归 一些有趣的递归应用 小结 问题 实验 编程作业 第7章 高级排序 希尔排序 划分 快速排序 基数排序 小结 问题 实验 编程作业 第8章 二叉树 为...

    Java数据结构和算法中文第二版

    递归的二分查找 汉诺(Hanoi)塔问题 归并排序 消除递归 一些有趣的递归应用 小结 问题 实验 编程作业 第7章 高级排序 希尔排序 划分 快速排序 基数排序 小结 问题 实验 编程作业 第8章 二叉树 为...

    C/C++常用算法手册.秦姣华(有详细书签).rar

    5.4.1 顺序表结构中的查找算法 145 5.4.2 链表结构中的查找算法 148 5.4.3 树结构中的查找算法 151 5.4.4 图结构中的查找算法 152 5.5 小结 153 第6章 基本数学问题 154 6.1 判断闰年 154 6.2 多项式计算 ...

    Java数据结构和算法(第二版)

    递归的二分查找 汉诺(Hanoi)塔问题 归并排序 消除递归 一些有趣的递归应用 小结 问题 实验 编程作业 第7章 高级排序 希尔排序 划分 快速排序 基数排序 小结 问题 实验 编程作业 第8章 二叉树 为什么使用二叉树? ...

    算法引论:一种创造性方法.[美]Udi Manber(带详细书签).pdf

    全书共分12章:第1章到第4章为介绍性内容,涉及数学归纳法、算法分析、数据结构等内容;第5章提出了与归纳证明进行类比的算法设计思想;第6章到第9章分别给出了4个领域的算法,如序列和集合的算法、图算法、几何算法...

    数据结构与算法分析_Java语言描述(第2版)

    小结 练习 参考文献 第2章 算法分析 2.1 数学基础 2.2 模型 2.3 要分析的问题 2.4 运行时间计算 2.4.1 一个简单的例子 2.4.2 一般法则 2.4.3 最大子序列和问题的求解 2.4.4 运行时间中的对数 2.4.5 检验你的分析 ...

    Java数据结构和算法中文第二版(1)

    递归的二分查找 汉诺(Hanoi)塔问题 归并排序 清除递归 一些有趣的递归应用 小结 问题 实验 编程作业 第7章 高级排序 希尔排序 划分 快速排序 基数排序 小结 问题 实验 编程作业 第8章 二叉树...

    Java数据结构和算法中文第二版(2)

    递归的二分查找 汉诺(Hanoi)塔问题 归并排序 清除递归 一些有趣的递归应用 小结 问题 实验 编程作业 第7章 高级排序 希尔排序 划分 快速排序 基数排序 小结 问题 实验 编程作业 第8章 二叉树...

    《C算法》((美国)Robert Sedgewick)清晰版[DJVU] 第二卷

    1.3 并集—查找算法 7 练习 17 1.4 展望 18 练习 19 1.5 小结 19 第2章 算法分析原理 22 2.1 实现与试验分析 22 练习 25 2.2 算法分析 25 练习 27 2.3 函数增长 27 练习 32 2.4 O记号 32 练习 35 2.5 基本递推式 36 ...

    算法心得:高效算法的奥秘(原书第2版).[美]Henry S.Warren,Jr(带详细书签).pdf

    11.1.2 二分查找 246 11.1.3 硬件算法 247 11.2 整数立方根 249 11.3 求整数幂 250 11.3.1 用n的二进制分解式计算xn 250 11.3.2 用Fortran语言计算2n 251 11.4 整数对数 252 11.4.1 以2为底的整数对数 253 ...

    数据结构与算法分析 Java语言描述第2版

    堆6.6 左式堆6.6.1 左式堆性质6.6.2 左式堆操作6.7 斜堆6.8 二项队列6.8.1 二项队列结构6.8.2 二项队列操作6.8.3 二项队列的实现6.9 标准库中的优先队列小结练习参考文献第7章 排序7.1 预备知识7.2 插入排序7.2.1 ...

    计算机二级公共基础知识

    1. 算法的基本概念 利用计算机算法为计算机解题的过程实际上是在实施某种算法。 (1)算法的基本特征 算法一般具有4个基本特征:可行性、确定性、有穷性、拥有足够的情报。 (2)算法的基本运算和操作 算法的基本...

    《C算法》((美国)Robert Sedgewick)清晰版[DJVU] 第一卷

    1.3 并集—查找算法 7 练习 17 1.4 展望 18 练习 19 1.5 小结 19 第2章 算法分析原理 22 2.1 实现与试验分析 22 练习 25 2.2 算法分析 25 练习 27 2.3 函数增长 27 练习 32 2.4 O记号 32 练习 35 2.5 基本递推式 36 ...

    数据结构实验

    如何利用二分查找算法在一个有序表中插入一个元素x,并保持表的有序性? 实验7:至少三种排序算法的程序实现 (第十六周星期三7、8节) 一、 实验目的 1.掌握简单插入排序、冒泡排序、快速排序、堆排序以及归并...

    谭浩强C语言程序设计,C++程序设计,严蔚敏数据结构,高一凡数据结构算法分析与实现.rar )

    10.8 有关指针的数据类型和指针运算的小结 167 10.8.1 有关指针的数据类型的小结 167 10.8.2 指针运算的小结 167 10.8.3 void 指针类型 168 11 结构体与共用体 11.1 定义一个结构的一般形式 170 11.2 结构类型变量的...

    谭浩强C语言程序设计,C++程序设计,严蔚敏数据结构,高一凡数据结构算法分析与实现.rar

    10.8 有关指针的数据类型和指针运算的小结 167 10.8.1 有关指针的数据类型的小结 167 10.8.2 指针运算的小结 167 10.8.3 void 指针类型 168 11 结构体与共用体 11.1 定义一个结构的一般形式 170 11.2 结构类型变量的...

Global site tag (gtag.js) - Google Analytics