Skip to content

Commit 066d15e

Browse files
chore: Add Interpolation Search (#308)
1 parent fef0b95 commit 066d15e

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package interpolationsearch
2+
3+
import "testing"
4+
5+
type searchTest struct {
6+
data []int
7+
key int
8+
expected int
9+
name string
10+
}
11+
12+
var searchTests = []searchTest{
13+
//Sanity
14+
{[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 1, 0, "Sanity"},
15+
{[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 5, 4, "Sanity"},
16+
{[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 10, 9, "Sanity"},
17+
//Absent
18+
{[]int{1, 4, 5, 6, 7, 10}, -25, -1, "Absent"},
19+
{[]int{1, 4, 5, 6, 7, 10}, 25, -1, "Absent"},
20+
//Empty slice
21+
{[]int{}, 2, -1, "Empty"},
22+
}
23+
24+
func TestInterpolationSearch(t *testing.T) {
25+
for _, test := range searchTests {
26+
actual := InterpolationSearch(test.data, test.key)
27+
if actual != test.expected {
28+
t.Errorf("test %s failed", test.name)
29+
}
30+
}
31+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package interpolationsearch
2+
3+
/*
4+
InterpolationSearch searches for the entity in the given sortedData.
5+
if the entity is present, it will return the index of the entity, if not -1 will be returned.
6+
see: https://en.wikipedia.org/wiki/Interpolation_search
7+
Complexity
8+
Worst: O(N)
9+
Average: O(log(log(N)) if the elements are uniformly distributed
10+
Best: O(1)
11+
12+
Example
13+
fmt.Println(InterpolationSearch([]int{1, 2, 9, 20, 31, 45, 63, 70, 100},100))
14+
*/
15+
func InterpolationSearch(sortedData []int, guess int) int {
16+
if len(sortedData) == 0 {
17+
return -1
18+
}
19+
20+
var (
21+
low, high = 0, len(sortedData) - 1
22+
lowVal, highVal = sortedData[low], sortedData[high]
23+
)
24+
25+
for lowVal != highVal && (lowVal <= guess) && (guess <= highVal) {
26+
mid := low + int(float64(float64((guess-lowVal)*(high-low))/float64(highVal-lowVal)))
27+
28+
// if guess is found, array can also have duplicate values, so scan backwards and find the first index
29+
if sortedData[mid] == guess {
30+
for mid > 0 && sortedData[mid-1] == guess {
31+
mid--
32+
}
33+
return mid
34+
35+
}
36+
37+
// adjust our guess and continue
38+
if sortedData[mid] > guess {
39+
high, highVal = mid-1, sortedData[high]
40+
41+
} else {
42+
low, lowVal = mid+1, sortedData[low]
43+
}
44+
45+
}
46+
47+
if guess == lowVal {
48+
return low
49+
}
50+
return -1
51+
}

0 commit comments

Comments
 (0)