LEFT | RIGHT |
1 // Copyright 2010 The Go Authors. All rights reserved. | 1 // Copyright 2010 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // This file implements binary search. | 5 // This file implements binary search. |
6 | 6 |
7 package sort | 7 package sort |
8 | 8 |
9 // Search uses binary search to find the index i for a value x in an indexable | 9 // Search uses binary search to find the index i for a value x in an indexable |
10 // and sorted data structure of n elements. The argument function f captures | 10 // and sorted data structure of n elements. The argument function f captures |
11 // the value to be searched for, how the elements are indexed, and how they are | 11 // the value to be searched for, how the elements are indexed, and how they are |
12 // sorted. It will often be passed as a closure. For instance, given a slice | 12 // sorted. It will often be passed as a closure. For instance, given a slice |
13 // of integers, []data, sorted in ascending order, the function | 13 // of integers, []data, sorted in ascending order, the function |
14 // | 14 // |
15 // func(i int) bool { return data[i] < 23 } | 15 // func(i int) bool { return data[i] < 23 } |
16 // | 16 // |
17 // can be used to search for the value 23 in data. The relationship expressed | 17 // can be used to search for the value 23 in data. The relationship expressed |
18 // by the function must be "less" if the elements are sorted in ascending | 18 // by the function must be "less" if the elements are sorted in ascending |
19 // order or "greater" if they are sorted in descending order. | 19 // order or "greater" if they are sorted in descending order. |
20 // The function f will be called with values of i in the range 0 to n-1. | 20 // The function f will be called with values of i in the range 0 to n-1. |
21 //· | 21 //· |
22 // For brevity, this discussion assumes ascending sort order. For descending | 22 // For brevity, this discussion assumes ascending sort order. For descending |
23 // order, replace < with >, and swap 'smaller' with 'larger'. | 23 // order, replace < with >, and swap 'smaller' with 'larger'. |
24 // | 24 // |
25 // Search returns the index i with: | 25 // Search returns the index i with: |
26 // | 26 // |
27 // data[i-1] < x && x <= data[i] | 27 // data[i-1] < x && x <= data[i] |
28 // | 28 // |
29 // where data[-1] is assumed to be smaller than any x and data[n] is | 29 // where data[-1] is assumed to be smaller than any x and data[n] is |
30 // assumed to be larger than any x. It is the responsibility of the | 30 // assumed to be larger than any x. Thus 0 <= i <= n and i is the first |
31 // caller to verify the actual presence by testing if data[i] == x. | 31 // index of x if x is present in the data. It is the responsibility of |
32 // Thus 0 <= i <= n and i is the first index of x if x is present in the data. | 32 // the caller to verify the actual presence by testing if i < n and |
| 33 // data[i] == x. |
33 // | 34 // |
34 // To complete the example above, the following code tries to find the element | 35 // To complete the example above, the following code tries to find the element |
35 // elem in an integer slice data sorted in ascending order: | 36 // elem in an integer slice data sorted in ascending order: |
36 // | 37 // |
37 // elem := 23 | 38 // elem := 23 |
38 // i := sort.Search(len(data), func(i int) bool { return data[i] < elem }) | 39 // i := sort.Search(len(data), func(i int) bool { return data[i] < elem }) |
39 // if i < len(data) && data[i] == elem { | 40 // if i < len(data) && data[i] == elem { |
40 // // elem is present at data[i] | 41 // // elem is present at data[i] |
41 // } else { | 42 // } else { |
42 // // elem is not present in data | 43 // // elem is not present in data |
43 // } | 44 // } |
44 func Search(n int, f func(int) bool) int { | 45 func Search(n int, f func(int) bool) int { |
45 i, j := 0, n | 46 i, j := 0, n |
46 for i+1 < j { | 47 for i+1 < j { |
47 h := i + (j-i)/2 // avoid overflow when computing h | 48 h := i + (j-i)/2 // avoid overflow when computing h |
48 » » // i <= h <= j | 49 » » // i < h < j |
49 if f(h) { | 50 if f(h) { |
50 // data[h] < x | 51 // data[h] < x |
51 i = h + 1 | 52 i = h + 1 |
52 } else { | 53 } else { |
53 // x <= data[h] | 54 // x <= data[h] |
54 j = h | 55 j = h |
55 } | 56 } |
56 } | 57 } |
57 // test the final element that the loop did not. | 58 // test the final element that the loop did not. |
58 if i < j && f(i) { | 59 if i < j && f(i) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 // Search returns the result of applying SearchInts to the receiver and x. | 93 // Search returns the result of applying SearchInts to the receiver and x. |
93 func (p IntArray) Search(x int) int { return SearchInts(p, x) } | 94 func (p IntArray) Search(x int) int { return SearchInts(p, x) } |
94 | 95 |
95 | 96 |
96 // Search returns the result of applying SearchFloats to the receiver and x. | 97 // Search returns the result of applying SearchFloats to the receiver and x. |
97 func (p FloatArray) Search(x float) int { return SearchFloats(p, x) } | 98 func (p FloatArray) Search(x float) int { return SearchFloats(p, x) } |
98 | 99 |
99 | 100 |
100 // Search returns the result of applying SearchStrings to the receiver and x. | 101 // Search returns the result of applying SearchStrings to the receiver and x. |
101 func (p StringArray) Search(x string) int { return SearchStrings(p, x) } | 102 func (p StringArray) Search(x string) int { return SearchStrings(p, x) } |
LEFT | RIGHT |