Go语言二分查找
Posted 携壶酌流霞
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go语言二分查找相关的知识,希望对你有一定的参考价值。
什么是二分查找
二分查找针对的是一个有序的数据集合,查找思想有点类似分治思想。每次都通过跟区间的中间元素对比,将待查找的区间缩小为之前的一半,直到找到要查找的元素,或者区间被缩小为 0。
时间复杂度分析
假设数据大小是 n,每次查找后数据都会缩小为原来的一半,也就是除以 2,最坏情况下,直到查找被缩小为空才停止。
可以看出来,这是一个等比数列。其中 n/2k=1 时,k 的值就是总共缩小的次数。而每一次缩小操作只涉及两个数据的大小比较,所以,经过了 k 次区间缩小操作,时间复杂度就是 O(k)。通过 n/2k=1,我们可以求得 k=log2n,所以时间复杂度就是 O(logn)。
代码实现
最简单的二分查找:就是在有序数组中不存在重复的元素。实现代码如下:
非递归代码实现
func bsearch(arr []int, n int, target int) int {
low := 0
height := n - 1
for low <= height {
mid := low + (height-low)>>1
if arr[mid] == target {
return mid
} else if arr[mid] < target {
low = mid + 1
} else {
height = mid - 1
}
}
return -1
}
// 二分查找递归实现
func bsearch(arr []int, n int, target int) int {
return bsearchInternal(arr, 0, n-1, target)
}
func bsearchInternal(arr []int, low, high, target int) int {
if low > high {
return -1
}
mid := low + ((high-low)>>1)
if arr[mid] == target {
return mid
} else if arr[mid] < target {
return bsearchInternal(arr, mid+1, high, target)
} else {
return bsearchInternal(arr, low, mid-1, target)
}
}
1、循环退出条件
注意是 low<=high,而不是 low<high
2、mid 的取值
mid := (low+high)/2这种写法很容易出问题,如果low和high都很大,两者之和就可能会溢出。改进的方法可以写成这样:mid := low+(high-low)/2,为了优化性能,除以2可以写成位运算,mid := low+((high-low)>>1)
3、low和high的更新
low= mid+1, high=mid-1
二分查找应用场景的局限性
首先,二分查找依赖的是循序表结构,简单点说就是数组
其次,二分查找针对的是有序数据
再此,数据量太小不适合二分查找
最后,数据量太大也不适合二分查找,因为数组结构是需要连续的空间
以上是关于Go语言二分查找的主要内容,如果未能解决你的问题,请参考以下文章