二分查找方法

4 篇文章 0 订阅

二分查找

将一组有序数组一分为二,将要查找元素与分割点比较,有三种情况:

1.查找元素比分割点大 。->在分割点右侧继续查找

2.查找元素比分割点小。->在分割点左侧继续查找

3.查找原始等于分割点。->直接返回。

    使用二分查找方法,每经过一次查找,查找范围缩小一半,如果数组元素个数为n,假设n是3的幂。第一次查找后,剩下N/2个元素继续查,第二次(n/2)/2个元素需要继续查。则第i次比较后,剩下n/2i个元素需要继续搜索。当i=log2n(以2为底n的对数),只剩下一个元素了,因而只需要再进行一次比较。因此二分查找方法在一个已排序数组中查找一个关键字,在最坏情况下只需log2n(以2为底n的对数)+1次比较操作,对于一个有1024个(210)元素的列表,二分搜索在最坏情况下只需11次比较,而顺序搜索方法在最坏情况下需1024次比较。
  二分搜索方法在每次比较之后,会将需要搜索的数组范围缩小一半,可以用变量low和high分别表示当前搜索的数组区域的首下标和尾下标,则变量mid的值就为(low+high)/2

时间复杂: O(lgn).

要求

  • 必须是有序的数组,并能支持随机访问

变形

  • 查找第一个值等于给定的
    • 在相等的时候做处理,向前查
  • 查找最后一个值等于给定的值
    • 在相等的时候做处理,向后查
  • 查找第一个大于等于给定的值
    • 判断边界减1
  • 查找最后一个小于等于给定的值
    • 判断边界加1

实际应用

  • 用户ip区间段查询
  • 用于相似度查询
  •   二分查找的优点

        折半查找的时间复杂度为O(logn),远远好于顺序查找的O(n)。

      二分查找的缺点

        虽然二分查找的效率高,但是要将表按关键字排序。而排序本身是一种很费时的运算。既使采用高效率的排序方法也要花费O(nlgn)的时间。

      适用情况

     

        二分查找只适用顺序存储结构。为保持表的有序性,在顺序结构里插入和删除都必须移动大量的结点。因此,二分查找特别适用于那种一经建立就很少改动、而又经常需要查找的线性表。

        对那些查找少而又经常需要改动的线性表,可采用链表作存储结构,进行顺序查找。链表上无法实现二分查找。

  • goland代码实现

  • package main
    
    import (
       "bufio"
       "fmt"
       "os"
       "strconv"
       "strings"
    )
    
    func cmd_search(arr []int, finddata int) int {
       low := 0
       high := len(arr) - 1
       for low <= high {
          mid := (low + high) / 2
          fmt.Println(mid)
          if arr[mid] > finddata {
             high = mid - 1
          } else if arr[mid] < finddata {
             low = mid + 1
          } else {
             return mid
          }
       }
       return -1
    }
    
    func main() {
       arr := []int{3, 4, 7, 9, 13, 45, 67, 89, 100, 180}
       // 排序前的数值
       fmt.Println("数组中的数据: ")
       fmt.Println(arr)
    
       fmt.Print("输入查找的值: ")
       reader := bufio.NewReader(os.Stdin)
       str, _ := reader.ReadString('\n')
       str = strings.Replace(str, " ", "", -1)
       str = strings.Replace(str, "\n", "", -1)
       m, _ := strconv.Atoi(str)
       cmd_search(arr,m)
    }
    

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值