diff --git a/src/main/java/com/thealgorithms/searches/TernarySearch.java b/src/main/java/com/thealgorithms/searches/TernarySearch.java
index 4d9f55ea9917..1071d172ef21 100644
--- a/src/main/java/com/thealgorithms/searches/TernarySearch.java
+++ b/src/main/java/com/thealgorithms/searches/TernarySearch.java
@@ -3,38 +3,44 @@
import com.thealgorithms.devutils.searches.SearchAlgorithm;
/**
- * A ternary search algorithm is a technique in computer science for finding the
- * minimum or maximum of a unimodal function The algorithm determines either
- * that the minimum or maximum cannot be in the first third of the domain or
- * that it cannot be in the last third of the domain, then repeats on the
- * remaining third.
+ * A ternary search algorithm is a divide-and-conquer algorithm that searches for
+ * a key in a sorted array by dividing the search domain into three parts.
*
*
- * Worst-case performance Θ(log3(N)) Best-case performance O(1) Average
- * performance Θ(log3(N)) Worst-case space complexity O(1)
+ * Worst-case performance: Θ(log3(N))
+ * Best-case performance: O(1)
+ * Average performance: Θ(log3(N))
+ * Worst-case space complexity: O(log3(N))
*
* @author Podshivalov Nikita (https://github.com/nikitap492)
* @see SearchAlgorithm
* @see IterativeBinarySearch
*/
-public class TernarySearch implements SearchAlgorithm {
+public final class TernarySearch implements SearchAlgorithm {
/**
- * @param arr The **Sorted** array in which we will search the element.
+ * Searches for a value in a sorted array using ternary search.
+ *
+ * @param arr The sorted array in which we will search for the element.
* @param value The value that we want to search for.
- * @return The index of the element if found. Else returns -1.
+ * @return The index of the element if found. Returns -1 if the array is null or empty, if value is null, or if not found.
*/
@Override
public > int find(T[] arr, T value) {
+ if (arr == null || arr.length == 0 || value == null) {
+ return -1;
+ }
return ternarySearch(arr, value, 0, arr.length - 1);
}
/**
- * @param arr The **Sorted** array in which we will search the element.
+ * Recursively searches for the specified key within the range [start, end].
+ *
+ * @param arr The sorted array in which we will search the element.
* @param key The value that we want to search for.
- * @param start The starting index from which we will start Searching.
- * @param end The ending index till which we will Search.
- * @return Returns the index of the Element if found. Else returns -1.
+ * @param start The starting index from which we will start searching.
+ * @param end The ending index till which we will search.
+ * @return Returns the index of the element if found. Else returns -1.
*/
private > int ternarySearch(T[] arr, T key, int start, int end) {
if (start > end) {
@@ -45,16 +51,22 @@ private > int ternarySearch(T[] arr, T key, int start, i
/* Second boundary: add 2/3 of length to start */
int mid2 = start + 2 * (end - start) / 3;
- if (key.compareTo(arr[mid1]) == 0) {
+ int cmp1 = key.compareTo(arr[mid1]);
+ if (cmp1 == 0) {
return mid1;
- } else if (key.compareTo(arr[mid2]) == 0) {
+ }
+
+ int cmp2 = key.compareTo(arr[mid2]);
+ if (cmp2 == 0) {
return mid2;
- } /* Search the first (1/3) rd part of the array.*/ else if (key.compareTo(arr[mid1]) < 0) {
- return ternarySearch(arr, key, start, --mid1);
- } /* Search 3rd (1/3)rd part of the array */ else if (key.compareTo(arr[mid2]) > 0) {
- return ternarySearch(arr, key, ++mid2, end);
- } /* Search middle (1/3)rd part of the array */ else {
- return ternarySearch(arr, key, mid1, mid2);
+ }
+
+ if (cmp1 < 0) {
+ return ternarySearch(arr, key, start, mid1 - 1);
+ } else if (cmp2 > 0) {
+ return ternarySearch(arr, key, mid2 + 1, end);
+ } else {
+ return ternarySearch(arr, key, mid1 + 1, mid2 - 1);
}
}
}
diff --git a/src/test/java/com/thealgorithms/searches/TernarySearchTest.java b/src/test/java/com/thealgorithms/searches/TernarySearchTest.java
index 367b595e55d9..fa62b3f8f847 100644
--- a/src/test/java/com/thealgorithms/searches/TernarySearchTest.java
+++ b/src/test/java/com/thealgorithms/searches/TernarySearchTest.java
@@ -1,6 +1,7 @@
package com.thealgorithms.searches;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
@@ -78,4 +79,65 @@ void testEdgeCaseEmptyArray() {
assertEquals(-1, index, "Should return -1 for an empty array");
}
+
+ @Test
+ void testNullArrayReturnsMinusOne() {
+ TernarySearch search = new TernarySearch();
+ assertEquals(-1, search.find(null, 5));
+ }
+
+ @Test
+ void testNullKeyReturnsMinusOne() {
+ Integer[] arr = {1, 2, 3, 4, 5};
+ TernarySearch search = new TernarySearch();
+ assertEquals(-1, search.find(arr, null));
+ }
+
+ @Test
+ void testSingleElementPresent() {
+ Integer[] arr = {42};
+ TernarySearch search = new TernarySearch();
+ assertEquals(0, search.find(arr, 42));
+ }
+
+ @Test
+ void testSingleElementAbsent() {
+ Integer[] arr = {42};
+ TernarySearch search = new TernarySearch();
+ assertEquals(-1, search.find(arr, 24));
+ }
+
+ @Test
+ void testTwoElements() {
+ Integer[] arr = {10, 20};
+ TernarySearch search = new TernarySearch();
+ assertEquals(0, search.find(arr, 10));
+ assertEquals(1, search.find(arr, 20));
+ assertEquals(-1, search.find(arr, 15));
+ }
+
+ @Test
+ void testMiddlePartitionSearch() {
+ Integer[] arr = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19};
+ TernarySearch search = new TernarySearch();
+ assertEquals(3, search.find(arr, 7));
+ assertEquals(4, search.find(arr, 9));
+ assertEquals(5, search.find(arr, 11));
+ }
+
+ @Test
+ void testDuplicateElements() {
+ Integer[] arr = {1, 2, 2, 2, 3};
+ TernarySearch search = new TernarySearch();
+ int index = search.find(arr, 2);
+ assertTrue(index >= 1 && index <= 3, "Index should be one of the occurrences of 2");
+ }
+
+ @Test
+ void testGenericStrings() {
+ String[] words = {"apple", "banana", "cherry", "date", "elderberry"};
+ TernarySearch search = new TernarySearch();
+ assertEquals(2, search.find(words, "cherry"));
+ assertEquals(-1, search.find(words, "fig"));
+ }
}