Skip to content

Commit 0182e31

Browse files
committed
Added TernarySearch Function
1 parent 38c5cca commit 0182e31

File tree

2 files changed

+140
-0
lines changed

2 files changed

+140
-0
lines changed

Search/TernarySearch.js

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/* Ternary search is similar to binary search but it divide the sorted array
2+
* into three parts and determine which part the key lies in. The array will
3+
* be divided into three intervals by using two middle points, mid1 and mid2.
4+
* The value of the key will first compared with the two mid points, the value
5+
* will be returned if there is a match. Then, if the value of the key is less
6+
* than mid1, narrow the interval to the first part. Else, if the value of the
7+
* key is greater than mid2, narrow the interval to the third part. Otherwise,
8+
* narrow the interval to the middle part. Repeat the steps until the value is
9+
* found or the interval is empty(value not found after checking all elements).
10+
*
11+
* Reference: https://www.geeksforgeeks.org/ternary-search/
12+
*/
13+
14+
/*
15+
* Doctests
16+
*
17+
* > ternarySearchRecursive([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3)
18+
* 2
19+
* > ternarySearchIterative([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 8)
20+
* 7
21+
* > ternarySearchRecursive([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0)
22+
* -1
23+
* > ternarySearchIterative([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 12)
24+
* -1
25+
* > ternarySearchRecursive(["Ali", "Cathrynli", "Josuke", "Thomas"], "Cathrynli")
26+
* 1
27+
* > ternarySearchRecursive(["Ali", "Cathrynli", "Josuke", "Thomas"], "Josuke")
28+
* 2
29+
* > ternarySearchRecursive(["Ali", "Cathrynli", "Josuke", "Thomas"], "Angela")
30+
* -1
31+
*/
32+
33+
function ternarySearchRecursive (arr, key, low = 0, high = arr.length - 1) {
34+
if (high >= low) {
35+
// find the mid1 and mid2
36+
const mid1 = Math.floor(low + (high - low) / 3)
37+
const mid2 = Math.floor(high - (high - low) / 3)
38+
39+
// check if key is found at any mid
40+
if (arr[mid1] === key) {
41+
// return index of key if found
42+
return mid1
43+
}
44+
if (arr[mid2] === key) {
45+
// return index of key if found
46+
return mid2
47+
}
48+
49+
// since the key is not found at mid,
50+
// check in which region it is present
51+
// and repeat the Search operation
52+
// in that region
53+
if (key < arr[mid1]) {
54+
// the key lies in between low and mid1
55+
return ternarySearchRecursive(arr, key, low, mid1 - 1)
56+
} else if (key > arr[mid2]) {
57+
// the key lies in between mid2 and high
58+
return ternarySearchRecursive(arr, key, mid2 + 1, high)
59+
} else {
60+
// the key lies in between mid1 and mid2
61+
return ternarySearchRecursive(arr, key, mid1 + 1, mid2 - 1)
62+
}
63+
} else {
64+
// if low > high => we have searched the whole array without finding the item
65+
return -1
66+
}
67+
}
68+
function ternarySearchIterative (arr, key, low = 0, high = arr.length - 1) {
69+
while (high >= low) {
70+
// find the mid1 and mid2
71+
const mid1 = Math.floor(low + (high - low) / 3)
72+
const mid2 = Math.floor(high - (high - low) / 3)
73+
74+
// check if key is found at any mid
75+
if (arr[mid1] === key) {
76+
// return index of key if found
77+
return mid1
78+
}
79+
if (arr[mid2] === key) {
80+
// return index of key if found
81+
return mid2
82+
}
83+
84+
// since the key is not found at mid,
85+
// check in which region it is present
86+
// and repeat the Search operation
87+
// in that region
88+
if (key < arr[mid1]) {
89+
// the key lies in between low and mid1
90+
high = mid1 - 1
91+
} else if (key > arr[mid2]) {
92+
// the key lies in between mid2 and high
93+
low = mid2 + 1
94+
} else {
95+
// the key lies in between mid1 and mid2
96+
low = mid1 + 1
97+
high = mid2 - 1
98+
}
99+
}
100+
// the key was not found
101+
return -1
102+
}
103+
104+
export { ternarySearchRecursive, ternarySearchIterative }

Search/test/TernarySearch.test.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { ternarySearchRecursive, ternarySearchIterative } from '../TernarySearch'
2+
3+
test('should return the index of a number in an array of numbers:', () => {
4+
const indexNumber = ternarySearchRecursive([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3)
5+
expect(indexNumber).toBe(2)
6+
})
7+
8+
test('should return the index of a number in an array of numbers:', () => {
9+
const indexNumber = ternarySearchIterative([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 8)
10+
expect(indexNumber).toBe(7)
11+
})
12+
13+
test('should return the index of a number in an array of numbers:', () => {
14+
const indexNumber = ternarySearchRecursive([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0)
15+
expect(indexNumber).toBe(-1)
16+
})
17+
18+
test('should return the index of a number in an array of numbers:', () => {
19+
const indexNumber = ternarySearchIterative([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 12)
20+
expect(indexNumber).toBe(-1)
21+
})
22+
23+
test('should return the index of a string in an array of strings:', () => {
24+
const indexNumber = ternarySearchRecursive(['Ali', 'Cathrynli', 'Josuke', 'Thomas'], 'Cathrynli')
25+
expect(indexNumber).toBe(1)
26+
})
27+
28+
test('should return the index of a string in an array of strings:', () => {
29+
const indexNumber = ternarySearchRecursive(['Ali', 'Cathrynli', 'Josuke', 'Thomas'], 'Josuke')
30+
expect(indexNumber).toBe(2)
31+
})
32+
33+
test('should return the index of a string in an array of strings:', () => {
34+
const indexNumber = ternarySearchRecursive(['Ali', 'Cathrynli', 'Josuke', 'Thomas'], 'Angela')
35+
expect(indexNumber).toBe(-1)
36+
})

0 commit comments

Comments
 (0)