Skip to content

Commit 8ae1f24

Browse files
authored
Merge pull request TheAlgorithms#151 from DTBUday/master
Added Ternary Search Algorithm
2 parents 7fe8fdc + 7447a9f commit 8ae1f24

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed

searches/ternary_search.py

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

0 commit comments

Comments
 (0)