Binary Search is a simple algorithm to find an item in an sorted array, and it’s usually referenced as a code sample to study when learning a new programming language.
Binary Search是一种简单的算法,可以在排序后的数组中查找项目,通常将其称为代码样本,以学习新的编程语言时进行研究。
功效 (Efficency)
It’s very efficient:
这非常有效:
Time: O(log n), it’s at worst logaritmic
时间: O(log n) ,对数最差
Space: 0(1), takes constant time
空间: 0(1) ,需要固定时间
理论 (Theory)
Given a sorted array, we pick the item Y in the middle and we compare it to the target value X.
给定一个排序数组,我们在中间选择项Y并将其与目标值X进行比较。
If Y matches X, we return the Y position and we exit.
如果Y与X匹配,则返回Y位置,然后退出。
We determine if X < Y, in this case we discard the right side, and we go in the middle of the left side, and we repeat the same operation as above.
我们确定是否X <Y,在这种情况下,我们丢弃右侧,然后移至左侧的中间,然后重复与上述相同的操作。
The search ends when Y finally matches X. If this does not happen, we return the position that X would have taken if it was in the array.
当Y最终与X匹配时,搜索结束。如果这没有发生,我们将返回X在数组中所处的位置。
实作 (Implementation)
We’re lucky, the Go standard library provides a binary tree implementation in its sort package, in sort.Search().
幸运的是,Go标准库在sort包中的sort.Search()提供了一个二叉树实现。
Let’s see the usage of the API, as taken from the package documentation, so we know what sort.Search should return:
让我们来看看API的用法,它来自软件包文档,因此我们知道什么样的sort.Search应该返回:
package main
import (
"fmt"
"sort"
)
func main() {
a := []int{1, 3, 6, 10, 15, 21, 28, 36, 45, 55}
x := 6
i := sort.Search(len(a), func(i int) bool { return a[i] >= x })
if i < len(a) && a[i] == x {
fmt.Printf("found %d at index %d in %v\n", x, i, a)
} else {
fmt.Printf("%d not found in %v\n", x, a)
}
}
sort.Search returns an index i, and we just need to make sure that that index actually contains x.
sort.Search返回一个索引i ,我们只需要确保该索引实际包含x 。
Of course we want to know how this is implemented internally. Since the standard library is written in Go, and open source, it’s really easy to see how sort.Search is implemented:
当然,我们想知道它是如何在内部实现的。 由于标准库是用Go语言和开源语言编写的,因此很容易看到sort.Search是如何实现的:
func Search(n int, f func(int) bool) int {
// Define f(-1) == false and f(n) == true.
// Invariant: f(i-1) == false, f(j) == true.
i, j := 0, n
for i < j {
h := i + (j-i)/2 // avoid overflow when computing h
// i ≤ h < j
if !f(h) {
i = h + 1 // preserves f(i-1) == false
} else {
j = h // preserves f(j) == true
}
}
// i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i.
return i
}
Let’s break it down:
让我们分解一下:
Given an array with length n, and a comparison function f (that internally evaluates x >= a[h]), we start iterating the array a.
给定一个长度为n的数组和一个比较函数f (内部计算x >= a[h] ),我们开始迭代数组a 。
Let’s use the actual values we use in the example, it’s easier to show what’s happening.
让我们使用示例中使用的实际值,可以更轻松地显示正在发生的事情。
Data:
数据:
a := []int{1, 3, 6, 10, 15, 21, 28, 36, 45, 55}
x := 6
Iteration 1:
迭代1:
iis0,jis9.i为0,j为9。his calculated as(0 + (9-0) / 2)=4h计算为(0 + (9-0) / 2)=4a[h]is15. This means we executej = ha[h]是15。 这意味着我们执行j = h
Iteration 2:
迭代2:
iis0,jis4.i为0,j为4。his calculated as(0 + (4-0) / 2)=2h计算为(0 + (4-0) / 2)=2a[h]is6. We found the position ofx, this means we returnh = 2a[h]是6。 我们找到了x的位置,这意味着我们返回h = 2
搜索逆序 (Searching reverse order)
Since we can pass a function to sort.Search, it’s easy to search on an array sorted in the reverse order, like
由于我们可以将函数传递给sort.Search ,因此很容易在以相反顺序排序的数组上进行搜索,例如
a := []int{55, 45, 36, 28, 21, 15, 10, 6, 3, 1}
x := 6
by passing a function that compares a[i] <= x instead of a[i] >= x.
通过传递比较a[i] <= x而不是a[i] >= x 。
i := sort.Search(len(a), func(i int) bool { return a[i] <= x })
翻译自: https://flaviocopes.com/golang-algorithms-binary-search/
本文深入探讨了二分查找算法的原理与效率,详细解释了其在排序数组中查找元素的过程,并提供了Go语言中的实现案例,包括直接使用标准库中的二分查找函数以及在逆序数组中的应用。

被折叠的 条评论
为什么被折叠?



