''' This is a type of divide and conquer algorithm which divides the search space into 3 parts and finds the target value based on the property of the array or list (usually monotonic property). Time Complexity : O(log3 N) Space Complexity : O(1) ''' import sys # This is the precision for this function which can be altered. # It is recommended for users to keep this number greater than or equal to 10. precision = 10 # This is the linear search that will occur after the search space has become smaller. def lin_search(left, right, A, target): for i in range(left, right+1): if(A[i] == target): return i # This is the iterative method of the ternary search algorithm. def ite_ternary_search(A, target): left = 0 right = len(A) - 1; while(True): if(left<right): if(right-left < precision): return lin_search(left,right,A,target) oneThird = (left+right)/3+1; twoThird = 2*(left+right)/3+1; if(A[oneThird] == target): return oneThird elif(A[twoThird] == target): return twoThird elif(target < A[oneThird]): right = oneThird-1 elif(A[twoThird] < target): left = twoThird+1 else: left = oneThird+1 right = twoThird-1 else: return None # This is the recursive method of the ternary search algorithm. def rec_ternary_search(left, right, A, target): if(left<right): if(right-left < precision): return lin_search(left,right,A,target) oneThird = (left+right)/3+1; twoThird = 2*(left+right)/3+1; if(A[oneThird] == target): return oneThird elif(A[twoThird] == target): return twoThird elif(target < A[oneThird]): return rec_ternary_search(left, oneThird-1, A, target) elif(A[twoThird] < target): return rec_ternary_search(twoThird+1, right, A, target) else: return rec_ternary_search(oneThird+1, twoThird-1, A, target) else: return None # This function is to check if the array is sorted. def __assert_sorted(collection): if collection != sorted(collection): raise ValueError('Collection must be sorted') return True if __name__ == '__main__': # For python 2.x and 3.x compatibility: 3.x has not raw_input builtin # otherwise 2.x's input builtin function is too "smart" if sys.version_info.major < 3: input_function = raw_input else: input_function = input user_input = input_function('Enter numbers separated by coma:\n') collection = [int(item) for item in user_input.split(',')] try: __assert_sorted(collection) except ValueError: sys.exit('Sequence must be sorted to apply the ternary search') target_input = input_function( 'Enter a single number to be found in the list:\n' ) target = int(target_input) result1 = ite_ternary_search(collection, target) result2 = rec_ternary_search(0, len(collection)-1, collection, target) if result2 is not None: print('Iterative search: {} found at positions: {}'.format(target, result1)) print('Recursive search: {} found at positions: {}'.format(target, result2)) else: print('Not found')