二分查找算法

二分查找

概述

二分查找(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)
}

参考

维基百科-二分查找算法

数据结构与算法之美

posted @ 2021-06-22 22:56  biby  阅读(907)  评论(0编辑  收藏  举报