sort: edit doc comment for Search

Change comment to be more generic,
with indexed data structure search as
one common use case.

Fix typo []data.

R=gri, rog
CC=golang-dev
https://golang.org/cl/3159041
This commit is contained in:
Russ Cox 2010-11-18 07:16:09 -05:00
parent 3fa6dcaca4
commit 19f0e4603d

View File

@ -6,61 +6,68 @@
package sort package sort
// Search uses binary search to find the index i for a value x in an indexable // Search uses binary search to find and return the smallest index i
// and sorted data structure of n elements. The argument function f captures // in [0, n) at which f(i) is false, assuming that on the range [0, n),
// the value to be searched for, how the elements are indexed, and how they are // f(i) == false implies f(i+1) == false. That is, Search requires that
// sorted. It will often be passed as a closure. For instance, given a slice // f is true for some (possibly empty) prefix of the input range [0, n)
// of integers, []data, sorted in ascending order, the function // and then false for the (possibly empty) remainder; Search returns
// the first false index. If there is no such index, Search returns n.
// Search calls f(i) only for i in the range [0, n).
// //
// func(i int) bool { return data[i] < 23 } // A common use of Search is to find the index i for a value x in
// a sorted, indexable data structure like an array or slice.
// In this case, the argument f, typically a closure, captures the value
// to be searched for, and how the data structure is indexed and
// ordered.
// //
// can be used to search for the value 23 in data. The relationship expressed // For instance, given a slice data sorted in ascending order,
// by the function must be "less" if the elements are sorted in ascending // the call Search(len(data), func(i int) bool { return data[i] < 23 })
// order or "greater" if they are sorted in descending order. // returns the smallest index i such that data[i] >= 23. If the caller
// The function f will be called with values of i in the range 0 to n-1. // wants to find whether 23 is in the slice, it must test data[i] == 23
// separately.
// //
// For brevity, this discussion assumes ascending sort order. For descending // Searching data sorted in descending order would use the >
// order, replace < with >, and swap 'smaller' with 'larger'. // operator instead of the < operator.
// //
// Search returns the index i with: // To complete the example above, the following code tries to find the value
// x in an integer slice data sorted in ascending order:
// //
// data[i-1] < x && x <= data[i] // x := 23
// // i := sort.Search(len(data), func(i int) bool { return data[i] < x })
// where data[-1] is assumed to be smaller than any x and data[n] is // if i < len(data) && data[i] == x {
// assumed to be larger than any x. Thus 0 <= i <= n and i is the smallest // // x is present at data[i]
// index of x if x is present in the data. It is the responsibility of
// the caller to verify the actual presence by testing if i < n and
// data[i] == x.
//
// To complete the example above, the following code tries to find the element
// elem in an integer slice data sorted in ascending order:
//
// elem := 23
// i := sort.Search(len(data), func(i int) bool { return data[i] < elem })
// if i < len(data) && data[i] == elem {
// // elem is present at data[i]
// } else { // } else {
// // elem is not present in data // // x is not present in data,
// // but i is the index where it would be inserted.
// }
//
// As a more whimsical example, this program guesses your number:
//
// func GuessingGame() {
// var s string
// fmt.Printf("Pick an integer from 0 to 100.\n")
// answer := sort.Search(100, func(i int) bool {
// fmt.Printf("Is your number > %d? ", i)
// fmt.Scanf("%s", &s)
// return s != "" && s[0] == 'y'
// })
// fmt.Printf("Your number is %d.\n", answer)
// } // }
// //
func Search(n int, f func(int) bool) int { func Search(n int, f func(int) bool) int {
// Define f(-1) == true and f(n) == false.
// Invariant: f(i-1) == true, f(j) == false.
i, j := 0, n i, j := 0, n
for i+1 < j { for i < j {
h := i + (j-i)/2 // avoid overflow when computing h h := i + (j-i)/2 // avoid overflow when computing h
// i < h < j // i h < j
if f(h) { if f(h) {
// data[h] < x i = h + 1 // preserves f(i-1) == true
i = h + 1
} else { } else {
// x <= data[h] j = h // preserves f(j) == false
j = h
} }
} }
// test the final element that the loop did not // i == j, f(i-1) == true, and f(j) (= f(i)) == false => answer is i.
if i < j && f(i) {
// data[i] < x
i++
}
return i return i
} }