Skip to content

Commit 6d19270

Browse files
committed
added interpolation search
1 parent d70b926 commit 6d19270

File tree

1 file changed

+102
-0
lines changed

1 file changed

+102
-0
lines changed

Diff for: searches/interpolation_search.py

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
"""
2+
This is pure python implementation of interpolation search algorithm
3+
"""
4+
from __future__ import print_function
5+
import bisect
6+
7+
8+
def interpolation_search(sorted_collection, item):
9+
"""Pure implementation of interpolation search algorithm in Python
10+
Be careful collection must be sorted, otherwise result will be
11+
unpredictable
12+
:param sorted_collection: some sorted collection with comparable items
13+
:param item: item value to search
14+
:return: index of found item or None if item is not found
15+
"""
16+
left = 0
17+
right = len(sorted_collection) - 1
18+
19+
while left <= right:
20+
point = left + ((item - sorted_collection[left]) * (right - left)) // (sorted_collection[right] - sorted_collection[left])
21+
22+
#out of range check
23+
if point<0 or point>=len(sorted_collection):
24+
return None
25+
26+
current_item = sorted_collection[point]
27+
if current_item == item:
28+
return point
29+
else:
30+
if item < current_item:
31+
right = point - 1
32+
else:
33+
left = point + 1
34+
return None
35+
36+
37+
def interpolation_search_by_recursion(sorted_collection, item, left, right):
38+
39+
"""Pure implementation of interpolation search algorithm in Python by recursion
40+
Be careful collection must be sorted, otherwise result will be
41+
unpredictable
42+
First recursion should be started with left=0 and right=(len(sorted_collection)-1)
43+
:param sorted_collection: some sorted collection with comparable items
44+
:param item: item value to search
45+
:return: index of found item or None if item is not found
46+
"""
47+
point = left + ((item - sorted_collection[left]) * (right - left)) // (sorted_collection[right] - sorted_collection[left])
48+
49+
#out of range check
50+
if point<0 or point>=len(sorted_collection):
51+
return None
52+
53+
if sorted_collection[point] == item:
54+
return point
55+
elif sorted_collection[point] > item:
56+
return interpolation_search_by_recursion(sorted_collection, item, left, point-1)
57+
else:
58+
return interpolation_search_by_recursion(sorted_collection, item, point+1, right)
59+
60+
def __assert_sorted(collection):
61+
"""Check if collection is sorted, if not - raises :py:class:`ValueError`
62+
:param collection: collection
63+
:return: True if collection is sorted
64+
:raise: :py:class:`ValueError` if collection is not sorted
65+
Examples:
66+
>>> __assert_sorted([0, 1, 2, 4])
67+
True
68+
>>> __assert_sorted([10, -1, 5])
69+
Traceback (most recent call last):
70+
...
71+
ValueError: Collection must be sorted
72+
"""
73+
if collection != sorted(collection):
74+
raise ValueError('Collection must be sorted')
75+
return True
76+
77+
78+
if __name__ == '__main__':
79+
import sys
80+
# For python 2.x and 3.x compatibility: 3.x has no raw_input builtin
81+
# otherwise 2.x's input builtin function is too "smart"
82+
if sys.version_info.major < 3:
83+
input_function = raw_input
84+
else:
85+
input_function = input
86+
87+
user_input = input_function('Enter numbers separated by comma:\n')
88+
collection = [int(item) for item in user_input.split(',')]
89+
try:
90+
__assert_sorted(collection)
91+
except ValueError:
92+
sys.exit('Sequence must be sorted to apply interpolation search')
93+
94+
target_input = input_function(
95+
'Enter a single number to be found in the list:\n'
96+
)
97+
target = int(target_input)
98+
result = interpolation_search(collection, target)
99+
if result is not None:
100+
print('{} found at positions: {}'.format(target, result))
101+
else:
102+
print('Not found')

0 commit comments

Comments
 (0)