diff --git a/src/main/java/com/search/IterativeTernarySearch.java b/src/main/java/com/search/IterativeTernarySearch.java new file mode 100644 index 000000000000..663388894d44 --- /dev/null +++ b/src/main/java/com/search/IterativeTernarySearch.java @@ -0,0 +1,51 @@ +package com.search; + +/** + * A iterative version of a ternary search algorithm + * This is better way to implement the ternary search, because a recursive version adds some overhead to a stack. + * But in java the compile can transform the recursive version to iterative implicitly, + * so there are no much differences between these two algorithms + *

+ * Worst-case performance Θ(log3(N)) + * Best-case performance O(1) + * Average performance Θ(log3(N)) + * Worst-case space complexity O(1) + */ +public final class IterativeTernarySearch { + + /** + * @param array The **Sorted** array in which we will search the element. + * @param value The value that we want to search for. + * @return The index of the element if found. + * Else returns -1. + */ + public static > int find(T[] array, T value) { + int left = 0; + int right = array.length - 1; + + while (right > left) { + int leftCompareTo = array[left].compareTo(value); + int rightCompareTo = array[right].compareTo(value); + + if (leftCompareTo == 0) { + return left; + } + + if (rightCompareTo == 0) { + return right; + } + + int leftThird = left + (right - left) / 3 + 1; + int rightThird = right - (right - left) / 3 - 1; + + if (array[leftThird].compareTo(value) <= 0) { + left = leftThird; + } else { + right = rightThird; + } + } + + return -1; + } + +} diff --git a/src/test/java/com/search/IterativeTernarySearchTest.java b/src/test/java/com/search/IterativeTernarySearchTest.java new file mode 100644 index 000000000000..f822417279e7 --- /dev/null +++ b/src/test/java/com/search/IterativeTernarySearchTest.java @@ -0,0 +1,26 @@ +package com.search; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class IterativeTernarySearchTest { + + @Test + void testIterativeTernarySearch() { + Integer[] arr1 = {1, 2, 3, 5, 8, 13, 21, 34, 55}; + Assertions.assertEquals(2, IterativeTernarySearch.find(arr1, 3), "Incorrect index"); + Assertions.assertEquals(0, IterativeTernarySearch.find(arr1, 1), "Incorrect index"); + Assertions.assertEquals(8, IterativeTernarySearch.find(arr1, 55), "Incorrect index"); + Assertions.assertEquals(-1, IterativeTernarySearch.find(arr1, -2), "Incorrect index"); + Assertions.assertEquals(-1, IterativeTernarySearch.find(arr1, 4), "Incorrect index"); + + String[] arr2 = {"A", "B", "C", "D"}; + Assertions.assertEquals(2, IterativeTernarySearch.find(arr2, "C"), "Incorrect index"); + Assertions.assertEquals(1, IterativeTernarySearch.find(arr2, "B"), "Incorrect index"); + Assertions.assertEquals(-1, IterativeTernarySearch.find(arr2, "F"), "Incorrect index"); + + String[] arr3 = {}; + Assertions.assertEquals(-1, IterativeTernarySearch.find(arr3, ""), "Incorrect index"); + } + +}