Skip to content

Commit b0dc46a

Browse files
authored
Merge pull request AllAlgorithms#29 from mani1soni/ternary_search
Ternary search
2 parents 6a02143 + 2ab1e53 commit b0dc46a

1 file changed

Lines changed: 107 additions & 0 deletions

File tree

searches/ternary_search.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
'''
2+
This is a type of divide and conquer algorithm which divides the search space into
3+
3 parts and finds the target value based on the property of the array or list
4+
(usually monotonic property).
5+
6+
Time Complexity : O(log3 N)
7+
Space Complexity : O(1)
8+
'''
9+
from __future__ import print_function
10+
11+
import sys
12+
13+
try:
14+
raw_input # Python 2
15+
except NameError:
16+
raw_input = input # Python 3
17+
18+
# This is the precision for this function which can be altered.
19+
# It is recommended for users to keep this number greater than or equal to 10.
20+
precision = 10
21+
22+
# This is the linear search that will occur after the search space has become smaller.
23+
def lin_search(left, right, A, target):
24+
for i in range(left, right+1):
25+
if(A[i] == target):
26+
return i
27+
28+
# This is the iterative method of the ternary search algorithm.
29+
def ite_ternary_search(A, target):
30+
left = 0
31+
right = len(A) - 1;
32+
while(True):
33+
if(left<right):
34+
35+
if(right-left < precision):
36+
return lin_search(left,right,A,target)
37+
38+
oneThird = (left+right)/3+1;
39+
twoThird = 2*(left+right)/3+1;
40+
41+
if(A[oneThird] == target):
42+
return oneThird
43+
elif(A[twoThird] == target):
44+
return twoThird
45+
46+
elif(target < A[oneThird]):
47+
right = oneThird-1
48+
elif(A[twoThird] < target):
49+
left = twoThird+1
50+
51+
else:
52+
left = oneThird+1
53+
right = twoThird-1
54+
else:
55+
return None
56+
57+
# This is the recursive method of the ternary search algorithm.
58+
def rec_ternary_search(left, right, A, target):
59+
if(left<right):
60+
61+
if(right-left < precision):
62+
return lin_search(left,right,A,target)
63+
64+
oneThird = (left+right)/3+1;
65+
twoThird = 2*(left+right)/3+1;
66+
67+
if(A[oneThird] == target):
68+
return oneThird
69+
elif(A[twoThird] == target):
70+
return twoThird
71+
72+
elif(target < A[oneThird]):
73+
return rec_ternary_search(left, oneThird-1, A, target)
74+
elif(A[twoThird] < target):
75+
return rec_ternary_search(twoThird+1, right, A, target)
76+
77+
else:
78+
return rec_ternary_search(oneThird+1, twoThird-1, A, target)
79+
else:
80+
return None
81+
82+
# This function is to check if the array is sorted.
83+
def __assert_sorted(collection):
84+
if collection != sorted(collection):
85+
raise ValueError('Collection must be sorted')
86+
return True
87+
88+
89+
if __name__ == '__main__':
90+
user_input = raw_input('Enter numbers separated by coma:\n').strip()
91+
collection = [int(item) for item in user_input.split(',')]
92+
93+
try:
94+
__assert_sorted(collection)
95+
except ValueError:
96+
sys.exit('Sequence must be sorted to apply the ternary search')
97+
98+
target_input = raw_input('Enter a single number to be found in the list:\n')
99+
target = int(target_input)
100+
result1 = ite_ternary_search(collection, target)
101+
result2 = rec_ternary_search(0, len(collection)-1, collection, target)
102+
103+
if result2 is not None:
104+
print('Iterative search: {} found at positions: {}'.format(target, result1))
105+
print('Recursive search: {} found at positions: {}'.format(target, result2))
106+
else:
107+
print('Not found')

0 commit comments

Comments
 (0)