1111
1212def interpolation_search (sorted_collection , item ):
1313"""Pure implementation of interpolation search algorithm in Python
14- Be careful collection must be sorted, otherwise result will be
14+ Be careful collection must be ascending sorted, otherwise result will be
1515 unpredictable
16- :param sorted_collection: some sorted collection with comparable items
16+ :param sorted_collection: some ascending sorted collection with comparable items
1717 :param item: item value to search
1818 :return: index of found item or None if item is not found
1919 """
2020left = 0
2121right = len (sorted_collection ) - 1
2222
2323while left <= right :
24+ #avoid devided by 0 during interpolation
25+ if sorted_collection [left ]== sorted_collection [right ]:
26+ if sorted_collection [left ]== item :
27+ return left
28+ else :
29+ return None
30+
2431point = left + ((item - sorted_collection [left ]) * (right - left )) // (sorted_collection [right ] - sorted_collection [left ])
2532
2633#out of range check
@@ -31,66 +38,97 @@ def interpolation_search(sorted_collection, item):
3138if current_item == item :
3239return point
3340else :
34- if item < current_item :
35- right = point - 1
36- else :
37- left = point + 1
41+ if point < left :
42+ right = left
43+ left = point
44+ elif point > right :
45+ left = right
46+ right = point
47+ else :
48+ if item < current_item :
49+ right = point - 1
50+ else :
51+ left = point + 1
3852return None
3953
40-
4154def interpolation_search_by_recursion (sorted_collection , item , left , right ):
4255
4356"""Pure implementation of interpolation search algorithm in Python by recursion
44- Be careful collection must be sorted, otherwise result will be
57+ Be careful collection must be ascending sorted, otherwise result will be
4558 unpredictable
4659 First recursion should be started with left=0 and right=(len(sorted_collection)-1)
47- :param sorted_collection: some sorted collection with comparable items
60+ :param sorted_collection: some ascending sorted collection with comparable items
4861 :param item: item value to search
4962 :return: index of found item or None if item is not found
5063 """
51- point = left + ((item - sorted_collection [left ]) * (right - left )) // (sorted_collection [right ] - sorted_collection [left ])
5264
65+ #avoid devided by 0 during interpolation
66+ if sorted_collection [left ]== sorted_collection [right ]:
67+ if sorted_collection [left ]== item :
68+ return left
69+ else :
70+ return None
71+
72+ point = left + ((item - sorted_collection [left ]) * (right - left )) // (sorted_collection [right ] - sorted_collection [left ])
73+
5374#out of range check
5475if point < 0 or point >= len (sorted_collection ):
5576return None
5677
5778if sorted_collection [point ] == item :
5879return point
59- elif sorted_collection [point ] > item :
60- return interpolation_search_by_recursion (sorted_collection , item , left , point - 1 )
80+ elif point < left :
81+ return interpolation_search_by_recursion (sorted_collection , item , point , left )
82+ elif point > right :
83+ return interpolation_search_by_recursion (sorted_collection , item , right , left )
6184else :
62- return interpolation_search_by_recursion (sorted_collection , item , point + 1 , right )
85+ if sorted_collection [point ] > item :
86+ return interpolation_search_by_recursion (sorted_collection , item , left , point - 1 )
87+ else :
88+ return interpolation_search_by_recursion (sorted_collection , item , point + 1 , right )
6389
6490def __assert_sorted (collection ):
65- """Check if collection is sorted, if not - raises :py:class:`ValueError`
91+ """Check if collection is ascending sorted, if not - raises :py:class:`ValueError`
6692 :param collection: collection
67- :return: True if collection is sorted
68- :raise: :py:class:`ValueError` if collection is not sorted
93+ :return: True if collection is ascending sorted
94+ :raise: :py:class:`ValueError` if collection is not ascending sorted
6995 Examples:
7096 >>> __assert_sorted([0, 1, 2, 4])
7197 True
7298 >>> __assert_sorted([10, -1, 5])
7399 Traceback (most recent call last):
74100 ...
75- ValueError: Collection must be sorted
101+ ValueError: Collection must be ascending sorted
76102 """
77103if collection != sorted (collection ):
78- raise ValueError ('Collection must be sorted' )
104+ raise ValueError ('Collection must be ascending sorted' )
79105return True
80106
81107
82108if __name__ == '__main__' :
83109import sys
84-
85- user_input = raw_input ('Enter numbers separated by comma:\n ' ).strip ()
110+
111+ """
112+ user_input = raw_input('Enter numbers separated by comma:\n ').strip()
86113 collection = [int(item) for item in user_input.split(',')]
87114 try:
88115 __assert_sorted(collection)
89116 except ValueError:
90- sys .exit ('Sequence must be sorted to apply interpolation search' )
117+ sys.exit('Sequence must be ascending sorted to apply interpolation search')
91118
92119 target_input = raw_input('Enter a single number to be found in the list:\n ')
93120 target = int(target_input)
121+ """
122+
123+ debug = 0
124+ if debug == 1 :
125+ collection = [10 ,30 ,40 ,45 ,50 ,66 ,77 ,93 ]
126+ try :
127+ __assert_sorted (collection )
128+ except ValueError :
129+ sys .exit ('Sequence must be ascending sorted to apply interpolation search' )
130+ target = 67
131+
94132result = interpolation_search (collection , target )
95133if result is not None :
96134print ('{} found at positions:{}' .format (target , result ))
0 commit comments