So, I have been preparing for an interview and I thought of coding up a Binary search on a Bitonic array for practice. A bitonic array has a bunch of numbers in increasing order at the beginning of the array and then a bunch of numbers in decreasing order after that. And the problem is to find out whether or not a number exists in the Bitonic array.
import java.util.Arrays;
import java.util.Scanner;
import java.util.Collections;
public class Bitonic{
private Integer[] array;
// This is the maximum possible number in the array.
private int maxPossibleValue = 45645454;
public Bitonic(int n, int inv)
{
// Make a n element array and initialize each position with a random value.
array = new Integer[n];
for(int i = 0; i < n; i++){
array[i] = (int)Math.floor(Math.random() * maxPossibleValue);
}
// inv is the inversion point where the numbers stop increasing and start decreasing.
// To make this artificially happen, I sorted one half of the array in ascending order
// And the other half in descending.
Arrays.sort(array, 0, inv);
Arrays.sort(array, Math.min(inv + 1, n), n, Collections.reverseOrder());
// Print the array.
System.out.println(Arrays.toString(array));
}
private int finder(int target, int start, int end){
System.out.printf("Processing: %d to %d\n", start, end);
int currentPoint = (int)Math.floor(end + start)/2;
int left = Math.max(start, currentPoint - 1);
int right = Math.min(end, currentPoint + 1);
int leftValue = array[left];
int rightValue = array[right];
int currentValue = array[currentPoint];
if(currentValue == target){
System.out.println("Found the value.");
return currentPoint;
}
if(start == end && currentValue != target){
return -1;
}
if(currentValue > leftValue && currentValue < rightValue){
// Behind inversion point.
if(currentValue < target){
return finder(target, right, end);
}
else{
int result = finder(target, start, left);
if(result != -1){
return result;
}
return finder(target, right, end);
}
}
else if(currentValue < leftValue && currentValue > rightValue){
// After inversion point.
if(currentValue < target){
return finder(target, start, left);
}
else{
int result = finder(target, right, end);
if(result != -1){
return result;
}
return finder(target, start, left);
}
}
else{
// At inversion point or at one of the extreme corners or a plateau.
int result = finder(target, right, end);
if(result != -1){
return result;
}
return finder(target, start, left);
}
}
public int find(int target){
// Set up the recursion for the binary search.
return finder(target, 0, array.length - 1);
}
public int get(int location){
return array[location];
}
public static void main(String args[]){
Scanner reader = new Scanner(System.in);
int n, inv;
n = reader.nextInt();
inv = reader.nextInt();
Bitonic BitonicArray = new Bitonic(n, inv);
int targetLoc = reader.nextInt();
int target = BitonicArray.get(targetLoc);
System.out.printf("Value Queried: %d\n", target);
int result = BitonicArray.find(target);
if(result != -1)
System.out.printf("Found it at: %d, value at that location: %d", result, BitonicArray.get(result));
else
System.out.println("Not found.");
}
}