Skip to main content

Ternary Search

Definition:​

Ternary search is a divide-and-conquer algorithm similar to binary search, but instead of dividing the array into two halves, it divides it into three parts. The array is split by examining two midpoints, and the search continues in the section where the target value lies. Ternary search is particularly useful in unimodal functions (functions that increase then decrease).

Characteristics:​

  • Divides into Three Parts:

    • Ternary search compares the target with two midpoints to decide which of the three parts to search next.
  • Unimodal Function:

    • In unimodal functions, ternary search is more effective as it narrows down the search space in logarithmic time.
  • Works on Sorted Data:

    • Like binary search, ternary search requires the array to be sorted.

Time Complexity:​

  • Best Case: O(1)O(1)
    In the best case, the target element is found at one of the midpoints after just one comparison.

  • Average and Worst Case: O(log3n)O(log_3 n)
    Since the array is divided into three parts, ternary search runs in logarithmic time, specifically log3nlog_3 n, where n is the number of elements.

Space Complexity:​

  • Iterative: O(1)O(1)
    The iterative version requires constant memory for storing low, mid1, mid2, and high indices.

  • Recursive: O(log3n)O(log_3 n)
    In the recursive version, the space complexity is proportional to the recursion depth.

C++ Implementation:​

#include <iostream>
using namespace std;

int ternarySearch(int arr[], int low, int high, int target) {
if (high >= low) {
int mid1 = low + (high - low) / 3;
int mid2 = high - (high - low) / 3;

if (arr[mid1] == target) {
return mid1; // Target found at mid1
}
if (arr[mid2] == target) {
return mid2; // Target found at mid2
}

if (target < arr[mid1]) {
return ternarySearch(arr, low, mid1 - 1, target); // Search in the first third
}
else if (target > arr[mid2]) {
return ternarySearch(arr, mid2 + 1, high, target); // Search in the third third
}
else {
return ternarySearch(arr, mid1 + 1, mid2 - 1, target); // Search in the middle third
}
}

return -1; // Target not found
}

int main() {
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int size = sizeof(arr) / sizeof(arr[0]);
int target = 5;

int result = ternarySearch(arr, 0, size - 1, target);

if (result != -1) {
cout << "Element found at index " << result << endl;
} else {
cout << "Element not found" << endl;
}

return 0;
}

Use Cases:​

  • Optimization Problems:

    • Ternary search is particularly useful in optimization problems where a function is unimodal, helping to find optimal points efficiently.
  • Advanced Data Structures:

    • It can be utilized in data structures that require finding minimum or maximum values, such as in certain algorithms related to graphs and networks.

Advantages and Disadvantages:​

Advantages:​

  • Useful for Unimodal Functions:

    • Ternary search excels in scenarios where the function being analyzed is unimodal, providing an effective way to find extrema.
  • Reduced Search Space:

    • By dividing the search space into three parts, it can potentially provide a better estimate of where to find the target.

Disadvantages:​

  • Less Efficient than Binary Search:

    • Ternary search has a time complexity of O(log3 n), which is generally slower than the O(log2 n) time complexity of binary search.
  • Increased Comparisons:

    • Each iteration requires two comparisons instead of one, which can lead to higher overhead in some cases.

Optimizations and Applications:​

  • Enhanced Algorithm Efficiency:
    • While it may not outperform binary search in terms of time complexity, it can be applied in specific scenarios to improve algorithm efficiency, particularly in optimization tasks.

Summary:​

Ternary search is a valuable algorithm for searching in sorted datasets and finding extrema in unimodal functions. Although it has a higher overhead than binary search, its unique approach can be advantageous in certain optimization problems. Ternary search finds its niche in specific applications, especially where the characteristics of the data allow for a three-way split.