• 二分查找算法


    二分查找

    概述

    二分查找(binary search)算法,也叫折半查找(half-interval search)算法。
    二分查找算法作用于有序的数据集合。每次都通过跟区间的中间元素对比,将待查找的区间缩小为之前的一半,直到找到要查找的元素,或者区间被缩小为零。
    二分的思想是每次取半,即每一次比较都使搜索范围缩小一半
    二分查找仅适合数据这种数据结构,并且必须是有序数组,如果非有序需要先排序
    二叉搜索数和B树结构基于二分查找算法
    如果是偶数,中间数有两位,则取较小的数,比如 0+(5-0)/2=2

    时间与空间复杂度

    • 时间复杂度
      假设数据大小是n,每次查找后数据都会缩小为原来的一半,也就是会除以2。最坏的情况,直到查找区间被缩小为空,才停止。
      被查找区间的大小变化:n,2/n,4/n,8/n...n/2^k...
      当n/2^k=1时,k就是总共被缩小的次数。
      每一次缩小操作只涉及两个数据的大小比较,因此,经过k次区间缩小操作,时间复杂度就是O(k)。通过n/2^k=1,可以求得k=log2n,所以时间复杂度就是O(logn)

    二分查找算法的递归与非递归实现

    • 递归实现
    package main
    
    import "fmt"
    
    func binary_search(arr []int, low, high, hkey int) int {
        if(low>high) {
            return -1
        }
        mid := low + (high-low)/2
        if(arr[mid]>hkey) {
            return binary_search(arr, low, mid-1, hkey)
        } else if(arr[mid]<hkey) {
            return binary_search(arr, mid+1, high, hkey)
        }
    
        return mid;
    }
    
    func main()  {
        arr := []int{1,2,3,4,5,6,7,8,9}
        v := binary_search(arr, 0, 8, 5)
        fmt.Println("The hkey is: ", v)
    }
    
    • 非递归实现
    package main
    
    import "fmt"
    
    func binarySearch(arr []int, hkey int) int {
        low, high := 0, len(arr)-1
        for low <= high {
            mid := low + (high-low)/2
            if(arr[mid] == hkey) {
                return mid
            } else if(arr[mid] < hkey) {
                low = mid+1
            } else if(arr[mid] > hkey) {
                high = mid-1
            }
        }
        return -1
    }
    
    func main()  {
        arr := []int{1,2,3,4,5,6,7,8,9}
        v := binarySearch(arr, 5)
        fmt.Println("The hkey is: ", v)
    }
    

    实战

    我们同样通过力扣上的例题来加深理解
    二分查找

    • 使用GO语言实现
    package main
    
    import "fmt"
    
    func search(nums []int, target int) int {
        low, high := 0, len(nums)-1
        return bSearch(nums, low, high, target)
    }
    
    func bSearch(nums []int, low, high, target int) int {
        if(low>high) {
            return -1
        }
        mid := low + (high-low)/2//向下取整
        if( nums[mid]>target ) {
            return bSearch(nums, low, mid-1, target)
        } else if( nums[mid]<target ) {
            return bSearch(nums, mid+1, high, target)
        }
    
        return mid
    }
    
    func main() {
        //nums := []int{-1,0,3,5,9,12}
        //nums := []int{1,2,3,4,5,6,7,8,9}
        nums := []int{-1,0,3,5,9,12}
        //target := 9
        //target := 5
        target := 2
        value := search(nums, target)
        fmt.Println(value)
    }
    

    参考

    维基百科-二分查找算法

    数据结构与算法之美

  • 相关阅读:
    关于<asp:checkBoxList>控件的对齐方法
    heckboxlist详细用法、checkboxlist用法、checkboxlist
    layoutit note
    查看linux启动的线程信息
    【转】如何修改maven工程jdk版本
    开源bug管理工具-Cynthia
    linux系统相关、硬件、资源
    Nginx文件服务器配置
    windows安装zookeeper单机版
    centos安装nginx
  • 原文地址:https://www.cnblogs.com/biby/p/14920688.html
Copyright © 2020-2023  润新知