Skip to content

Commit 81a19a7

Browse files
authored
Adding the interpolation search algorithm (#686)
* adding interpolation search * requested changes, tests, readme * add to __init__.py * add interpolation_search * add interpolation_search to README * add interpolation_search to README
1 parent 20c1c4e commit 81a19a7

File tree

4 files changed

+69
-2
lines changed

4 files changed

+69
-2
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ If you want to uninstall algorithms, it is as simple as:
258258
- [search_rotate](algorithms/search/search_rotate.py)
259259
- [jump_search](algorithms/search/jump_search.py)
260260
- [next_greatest_letter](algorithms/search/next_greatest_letter.py)
261+
- [interpolation_search](algorithms/search/interpolation_search.py)
261262
- [set](algorithms/set)
262263
- [randomized_set](algorithms/set/randomized_set.py)
263264
- [set_covering](algorithms/set/set_covering.py)

algorithms/search/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@
99
from .search_rotate import *
1010
from .jump_search import *
1111
from .next_greatest_letter import *
12+
from .interpolation_search import *
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
"""
2+
Python implementation of the Interpolation Search algorithm.
3+
Given a sorted array in increasing order, interpolation search calculates
4+
the starting point of its search according to the search key.
5+
6+
FORMULA: start_pos = low + [ (x - arr[low])*(high - low) / (arr[high] - arr[low]) ]
7+
8+
Doc: https://en.wikipedia.org/wiki/Interpolation_search
9+
10+
Time Complexity: O(log2(log2 n)) for average cases, O(n) for the worst case.
11+
The algorithm performs best with uniformly distributed arrays.
12+
"""
13+
14+
from typing import List
15+
16+
17+
def interpolation_search(array: List[int], search_key: int) -> int:
18+
"""
19+
:param array: The array to be searched.
20+
:param search_key: The key to be searched in the array.
21+
22+
:returns: Index of search_key in array if found, else -1.
23+
24+
Example
25+
26+
>>> interpolation_search([1, 10, 12, 15, 20, 41, 55], 20)
27+
4
28+
>>> interpolation_search([5, 10, 12, 14, 17, 20, 21], 55)
29+
-1
30+
31+
"""
32+
33+
# highest and lowest index in array
34+
high = len(array) - 1
35+
low = 0
36+
37+
while low <= high and search_key in range(low, array[high] + 1):
38+
# calculate the search position
39+
pos = low + int(((search_key - array[low]) *
40+
(high - low) / (array[high] - array[low])))
41+
42+
# if array[pos] equals the search_key then return pos as the index
43+
if search_key == array[pos]:
44+
return pos
45+
# if the search_key is greater than array[pos] restart the search with the
46+
# subarray greater than array[pos]
47+
elif search_key > array[pos]:
48+
low = pos + 1
49+
# in this case start the search with the subarray smaller than current array[pos]
50+
elif search_key < array[pos]:
51+
high = pos - 1
52+
53+
return -1

tests/test_search.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@
99
find_min_rotate, find_min_rotate_recur,
1010
search_rotate, search_rotate_recur,
1111
jump_search,
12-
next_greatest_letter, next_greatest_letter_v1, next_greatest_letter_v2
12+
next_greatest_letter, next_greatest_letter_v1, next_greatest_letter_v2,
13+
interpolation_search
1314
)
1415

1516
import unittest
1617

18+
1719
class TestSuite(unittest.TestCase):
1820

1921
def test_first_occurrence(self):
@@ -56,7 +58,7 @@ def test_linear_search(self):
5658
self.assertEqual(-1, linear_search(array, -1))
5759

5860
def test_search_insert(self):
59-
array = [1,3,5,6]
61+
array = [1, 3, 5, 6]
6062
self.assertEqual(2, search_insert(array, 5))
6163
self.assertEqual(1, search_insert(array, 2))
6264
self.assertEqual(4, search_insert(array, 7))
@@ -122,6 +124,16 @@ def test_next_greatest_letter(self):
122124
self.assertEqual("c", next_greatest_letter_v1(letters, target))
123125
self.assertEqual("c", next_greatest_letter_v2(letters, target))
124126

127+
def test_interpolation_search(self):
128+
array = [0, 3, 5, 5, 9, 12, 12, 15, 16, 19, 20]
129+
self.assertEqual(1, interpolation_search(array, 3))
130+
self.assertEqual(2, interpolation_search(array, 5))
131+
self.assertEqual(6, interpolation_search(array, 12))
132+
self.assertEqual(-1, interpolation_search(array, 22))
133+
self.assertEqual(-1, interpolation_search(array, -10))
134+
self.assertEqual(10, interpolation_search(array, 20))
135+
136+
125137
if __name__ == '__main__':
126138

127139
unittest.main()

0 commit comments

Comments
 (0)