Skip to content

Add tests, remove main in IterativeTernarySearch #5668

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
3 changes: 3 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
* [IsPowerTwo](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/IsPowerTwo.java)
* [LowestSetBit](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/LowestSetBit.java)
* [NonRepeatingNumberFinder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java)
* [NumberAppearingOddTimes](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/NumberAppearingOddTimes.java)
* [NumbersDifferentSigns](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/NumbersDifferentSigns.java)
* [ReverseBits](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/ReverseBits.java)
* [SingleBitOperations](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/SingleBitOperations.java)
Expand Down Expand Up @@ -638,6 +639,7 @@
* [IsPowerTwoTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/IsPowerTwoTest.java)
* [LowestSetBitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/LowestSetBitTest.java)
* [NonRepeatingNumberFinderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinderTest.java)
* [NumberAppearingOddTimesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/NumberAppearingOddTimesTest.java)
* [NumbersDifferentSignsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/NumbersDifferentSignsTest.java)
* [ReverseBitsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/ReverseBitsTest.java)
* [SingleBitOperationsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java)
Expand Down Expand Up @@ -969,6 +971,7 @@
* [BreadthFirstSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/BreadthFirstSearchTest.java)
* [DepthFirstSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/DepthFirstSearchTest.java)
* [HowManyTimesRotatedTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/HowManyTimesRotatedTest.java)
* [IterativeTernarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/IterativeTernarySearchTest.java)
* [KMPSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/KMPSearchTest.java)
* [OrderAgnosticBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/OrderAgnosticBinarySearchTest.java)
* [PerfectBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/PerfectBinarySearchTest.java)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
package com.thealgorithms.searches;

import com.thealgorithms.devutils.searches.SearchAlgorithm;
import java.util.Arrays;
import java.util.Random;
import java.util.stream.Stream;

/**
* 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
* An iterative implementation of the Ternary Search algorithm.
*
* <p>
* Worst-case performance Θ(log3(N)) Best-case performance O(1) Average
* performance Θ(log3(N)) Worst-case space complexity O(1)
* Ternary search is a divide-and-conquer algorithm that splits the array into three parts
* instead of two, as in binary search. This implementation is iterative, reducing the overhead
* associated with recursive function calls. However, the recursive version can also be optimized
* by the Java compiler to resemble the iterative version, resulting in similar performance.
*
* <p>
* Worst-case performance: Θ(log3(N))<br>
* Best-case performance: O(1)<br>
* Average performance: Θ(log3(N))<br>
* Worst-case space complexity: O(1)
*
* <p>
* This class implements the {@link SearchAlgorithm} interface, providing a generic search method
* for any comparable type.
*
* @author Podshivalov Nikita (https://github.com/nikitap492)
* @see SearchAlgorithm
* @see TernarySearch
* @since 2018-04-13
Expand All @@ -25,6 +29,13 @@ public class IterativeTernarySearch implements SearchAlgorithm {

@Override
public <T extends Comparable<T>> int find(T[] array, T key) {
if (array == null || array.length == 0 || key == null) {
return -1;
}
if (array.length == 1) {
return array[0].compareTo(key) == 0 ? 0 : -1;
}

int left = 0;
int right = array.length - 1;

Expand All @@ -50,23 +61,4 @@ public <T extends Comparable<T>> int find(T[] array, T key) {

return -1;
}

public static void main(String[] args) {
// just generate data
Random r = new Random();
int size = 100;
int maxElement = 100000;
Integer[] integers = Stream.generate(() -> r.nextInt(maxElement)).limit(size).sorted().toArray(Integer[] ::new);

// the element that should be found
Integer shouldBeFound = integers[r.nextInt(size - 1)];

IterativeTernarySearch search = new IterativeTernarySearch();
int atIndex = search.find(integers, shouldBeFound);

System.out.printf("Should be found: %d. Found %d at index %d. An array length %d%n", shouldBeFound, integers[atIndex], atIndex, size);

int toCheck = Arrays.binarySearch(integers, shouldBeFound);
System.out.printf("Found by system method at an index: %d. Is equal: %b%n", toCheck, toCheck == atIndex);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package com.thealgorithms.searches;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.Test;

/**
* Unit tests for the IterativeTernarySearch class.
*/
class IterativeTernarySearchTest {

/**
* Test for basic ternary search functionality when the element is found.
*/
@Test
void testTernarySearchFound() {
IterativeTernarySearch ternarySearch = new IterativeTernarySearch();
Integer[] array = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512};
Integer key = 128;
int expectedIndex = 7; // Index of the key in the array
assertEquals(expectedIndex, ternarySearch.find(array, key), "The index of the found element should be 7.");
}

/**
* Test for ternary search when the element is not present in the array.
*/
@Test
void testTernarySearchNotFound() {
IterativeTernarySearch ternarySearch = new IterativeTernarySearch();
Integer[] array = {1, 2, 4, 8, 16};
Integer key = 6; // Element not present in the array
assertEquals(-1, ternarySearch.find(array, key), "The element should not be found in the array.");
}

/**
* Test for ternary search with the first element as the key.
*/
@Test
void testTernarySearchFirstElement() {
IterativeTernarySearch ternarySearch = new IterativeTernarySearch();
Integer[] array = {1, 2, 4, 8, 16};
Integer key = 1; // First element
assertEquals(0, ternarySearch.find(array, key), "The index of the first element should be 0.");
}

/**
* Test for ternary search with the last element as the key.
*/
@Test
void testTernarySearchLastElement() {
IterativeTernarySearch ternarySearch = new IterativeTernarySearch();
Integer[] array = {1, 2, 4, 8, 16};
Integer key = 16; // Last element
assertEquals(4, ternarySearch.find(array, key), "The index of the last element should be 4.");
}

/**
* Test for ternary search with a single element present.
*/
@Test
void testTernarySearchSingleElementFound() {
IterativeTernarySearch ternarySearch = new IterativeTernarySearch();
Integer[] array = {1};
Integer key = 1; // Only element present
assertEquals(0, ternarySearch.find(array, key), "The index of the single element should be 0.");
}

/**
* Test for ternary search with a single element not present.
*/
@Test
void testTernarySearchSingleElementNotFound() {
IterativeTernarySearch ternarySearch = new IterativeTernarySearch();
Integer[] array = {1};
Integer key = 2; // Key not present
assertEquals(-1, ternarySearch.find(array, key), "The element should not be found in the array.");
}

/**
* Test for ternary search with an empty array.
*/
@Test
void testTernarySearchEmptyArray() {
IterativeTernarySearch ternarySearch = new IterativeTernarySearch();
Integer[] array = {}; // Empty array
Integer key = 1; // Key not present
assertEquals(-1, ternarySearch.find(array, key), "The element should not be found in an empty array.");
}

/**
* Test for ternary search on a large array.
*/
@Test
void testTernarySearchLargeArray() {
IterativeTernarySearch ternarySearch = new IterativeTernarySearch();
Integer[] array = new Integer[10000];
for (int i = 0; i < array.length; i++) {
array[i] = i * 2;
} // Array from 0 to 19998, step 2
Integer key = 9998; // Present in the array
assertEquals(4999, ternarySearch.find(array, key), "The index of the found element should be 4999.");
}

/**
* Test for ternary search on large array with a non-existent key.
*/
@Test
void testTernarySearchLargeArrayNotFound() {
IterativeTernarySearch ternarySearch = new IterativeTernarySearch();
Integer[] array = new Integer[10000];
for (int i = 0; i < array.length; i++) {
array[i] = i * 2;
} // Array from 0 to 19998, step 2
Integer key = 9999; // Key not present
assertEquals(-1, ternarySearch.find(array, key), "The element should not be found in the array.");
}
}