Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions Search/TernarySearch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/* Ternary search is similar to binary search but it divide the sorted array
* into three parts and determine which part the key lies in. The array will
* be divided into three intervals by using two middle points, mid1 and mid2.
* The value of the key will first compared with the two mid points, the value
* will be returned if there is a match. Then, if the value of the key is less
* than mid1, narrow the interval to the first part. Else, if the value of the
* key is greater than mid2, narrow the interval to the third part. Otherwise,
* narrow the interval to the middle part. Repeat the steps until the value is
* found or the interval is empty(value not found after checking all elements).
*
* Reference: https://www.geeksforgeeks.org/ternary-search/
*/

/*
* Doctests
*
* > ternarySearchRecursive([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3)
* 2
* > ternarySearchIterative([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 8)
* 7
* > ternarySearchRecursive([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0)
* -1
* > ternarySearchIterative([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 12)
* -1
* > ternarySearchRecursive(["Ali", "Cathrynli", "Josuke", "Thomas"], "Cathrynli")
* 1
* > ternarySearchRecursive(["Ali", "Cathrynli", "Josuke", "Thomas"], "Josuke")
* 2
* > ternarySearchRecursive(["Ali", "Cathrynli", "Josuke", "Thomas"], "Angela")
* -1
*/

function ternarySearchRecursive (arr, key, low = 0, high = arr.length - 1) {
if (high >= low) {
// find the mid1 and mid2
const mid1 = Math.floor(low + (high - low) / 3)
const mid2 = Math.floor(high - (high - low) / 3)

// check if key is found at any mid
if (arr[mid1] === key) {
// return index of key if found
return mid1
}
if (arr[mid2] === key) {
// return index of key if found
return mid2
}

// since the key is not found at mid,
// check in which region it is present
// and repeat the Search operation
// in that region
if (key < arr[mid1]) {
// the key lies in between low and mid1
return ternarySearchRecursive(arr, key, low, mid1 - 1)
} else if (key > arr[mid2]) {
// the key lies in between mid2 and high
return ternarySearchRecursive(arr, key, mid2 + 1, high)
} else {
// the key lies in between mid1 and mid2
return ternarySearchRecursive(arr, key, mid1 + 1, mid2 - 1)
}
} else {
// if low > high => we have searched the whole array without finding the item
return -1
}
}
function ternarySearchIterative (arr, key, low = 0, high = arr.length - 1) {
while (high >= low) {
// find the mid1 and mid2
const mid1 = Math.floor(low + (high - low) / 3)
const mid2 = Math.floor(high - (high - low) / 3)

// check if key is found at any mid
if (arr[mid1] === key) {
// return index of key if found
return mid1
}
if (arr[mid2] === key) {
// return index of key if found
return mid2
}

// since the key is not found at mid,
// check in which region it is present
// and repeat the Search operation
// in that region
if (key < arr[mid1]) {
// the key lies in between low and mid1
high = mid1 - 1
} else if (key > arr[mid2]) {
// the key lies in between mid2 and high
low = mid2 + 1
} else {
// the key lies in between mid1 and mid2
low = mid1 + 1
high = mid2 - 1
}
}
// the key was not found
return -1
}

export { ternarySearchRecursive, ternarySearchIterative }
36 changes: 36 additions & 0 deletions Search/test/TernarySearch.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { ternarySearchRecursive, ternarySearchIterative } from '../TernarySearch'

test('should return the index of a number in an array of numbers:', () => {
const indexNumber = ternarySearchRecursive([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3)
expect(indexNumber).toBe(2)
})

test('should return the index of a number in an array of numbers:', () => {
const indexNumber = ternarySearchIterative([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 8)
expect(indexNumber).toBe(7)
})

test('should return the index of a number in an array of numbers:', () => {
const indexNumber = ternarySearchRecursive([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0)
expect(indexNumber).toBe(-1)
})

test('should return the index of a number in an array of numbers:', () => {
const indexNumber = ternarySearchIterative([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 12)
expect(indexNumber).toBe(-1)
})

test('should return the index of a string in an array of strings:', () => {
const indexNumber = ternarySearchRecursive(['Ali', 'Cathrynli', 'Josuke', 'Thomas'], 'Cathrynli')
expect(indexNumber).toBe(1)
})

test('should return the index of a string in an array of strings:', () => {
const indexNumber = ternarySearchRecursive(['Ali', 'Cathrynli', 'Josuke', 'Thomas'], 'Josuke')
expect(indexNumber).toBe(2)
})

test('should return the index of a string in an array of strings:', () => {
const indexNumber = ternarySearchRecursive(['Ali', 'Cathrynli', 'Josuke', 'Thomas'], 'Angela')
expect(indexNumber).toBe(-1)
})