|
| 1 | +## Ternary Search |
| 2 | +Ternary search is a divide-and-conquer search algorithm. It is mandatory for the array (in which you will search for an element) to be sorted before we begin the search. In this search, after each iteration it neglects ⅓ part of the array and repeats the same operations on the remaining ⅔. |
| 3 | +### Algorithm |
| 4 | + |
| 5 | +The steps involved in this algorithm are: |
| 6 | +(The list must be in sorted order) |
| 7 | + |
| 8 | +- **Step 1**: Divide the search space (initially, the list) in three parts (with two mid-points: `mid1` and `mid2`) |
| 9 | +- **Step 2**: The target element is compared with the edge elements that is elements at location `mid1`, `mid2` and the end of the search space. If element matches, go to step 3 else predict in which section the target element lies. The search space is reduced to `1/3`rd. If the element is not in the list, go to step 4 or to step 1. |
| 10 | +- **Step 3**: Element found. Return index and exit. |
| 11 | +- **Step 4**: Element not found. Exit. |
| 12 | +### Recursive algorithm |
| 13 | + |
| 14 | + def ternary_search(f, left, right, absolute_precision) -> float: |
| 15 | + """Left and right are the current bounds; |
| 16 | + the maximum is between them. |
| 17 | + """ |
| 18 | + if abs(right - left) < absolute_precision: |
| 19 | + return (left + right) / 2 |
| 20 | + |
| 21 | + left_third = (2*left + right) / 3 |
| 22 | + right_third = (left + 2*right) / 3 |
| 23 | + |
| 24 | + if f(left_third) < f(right_third): |
| 25 | + return ternary_search(f, left_third, right, absolute_precision) |
| 26 | + else: |
| 27 | + return ternary_search(f, left, right_third, absolute_precision) |
| 28 | +### Iterative Algorithm |
| 29 | + |
| 30 | + def ternary_search(f, left, right, absolute_precision) -> float: |
| 31 | + """Find maximum of unimodal function f() within [left, right] |
| 32 | + To find the minimum, reverse the if/else statement or reverse the comparison. |
| 33 | + """ |
| 34 | + while abs(right - left) >= absolute_precision: |
| 35 | + left_third = left + (right - left) / 3 |
| 36 | + right_third = right - (right - left) / 3 |
| 37 | + |
| 38 | + if f(left_third) < f(right_third): |
| 39 | + left = left_third |
| 40 | + else: |
| 41 | + right = right_third |
| 42 | + |
| 43 | + # Left and right are the current bounds; the maximum is between them |
| 44 | + return (left + right) / 2 |
| 45 | + |
| 46 | +### Complexity |
| 47 | +- Worst case time complexity: `O(log N)` |
| 48 | +- Average case time complexity: `O(log N)` |
| 49 | +- Best case time complexity: `O(1)` |
| 50 | +- Space complexity: `O(1)` |
| 51 | +### Applications |
| 52 | + |
| 53 | +- This concept is used in unimodal functions to determine the maximum or minimum value of that function. Unimodal functions are functions that, have a single highest value. |
| 54 | +- Can be used to search for where the derivative is zero in Newton's method as an optimization. |
| 55 | + |
| 56 | +### Instruction for Running code: |
| 57 | + - C |
| 58 | + ``` |
| 59 | + gcc ternarySearch.c |
| 60 | + ./a.out |
| 61 | + ``` |
| 62 | + - Cpp |
| 63 | +
|
| 64 | + ```` |
| 65 | + g++ ternarySearch.cpp |
| 66 | + ./a.out |
| 67 | + ```` |
| 68 | +- Java |
| 69 | +
|
| 70 | + ``` |
| 71 | + javac ternarySearch.java |
| 72 | + java ternarySearch.class |
| 73 | + ``` |
| 74 | +- Python |
| 75 | + ``` |
| 76 | + python3 ternarySearch.py |
| 77 | + ``` |
0 commit comments