recursion method in the binary search - java

I'm trying to implement a binary algorithm but I really don't know how to write this program using a recursion method. Could someone help me please write this method?
I have already written the easiest way for me:
import Prog1Tools.IOTools;
public class BinarySearch {
public static void showArray(int[] array) {
for(int x : array) System.out.print (x + " ");
System.out.println ();
}
public static void fillArray(int[] array, int arrayFirst) {
int i = 0;
while (i < array.length){
array[i] = arrayFirst;
i++;
arrayFirst++;
}
}
public static void main(String[] args) {
int l, p, s;
int arrayEnd = IOTools.readInt("Type a last number in the array : ");
int arrayFirst = IOTools.readInt("Type a first number in the array : ");
int[] nums = new int[arrayEnd+1-arrayFirst ];
fillArray(nums, arrayFirst);
showArray(nums);
System.out.println ("Could you please choose a number from the array above? " );
l = 0;
p = arrayEnd-arrayFirst;
loop: while (l <= p) {
s = (l + p) / 2;
String question = IOTools.readString("Is your number "+nums[s] + " or higher ?[You can answer: yes or higher] ");
switch (question){
case "yes":
System.out.println("I found a number "+nums[s]+" Your number has an index "+s +" in the array");
break loop;
case "higher":
l = s + 1;
break;
}
}
}
}
I tried such method but it doesn't work
public static int recursiveBinarySearch(int[] sortedArray, int start, int end, String question) {
if (start < end) {
int mid = start + (end - start) / 2;
if (question=="higher") {
return recursiveBinarySearch(sortedArray, start, mid, question);
} else if (question=="lower") {
return recursiveBinarySearch(sortedArray, mid+1, end , question);
} else {
return mid;
}
}
return -(start + 1);
}

public boolean binaryS(int A[],int left, int right, int x){
int middle;
//check if there is any array left to search
if (left > right) return false;
//determine the middle of this array section
middle = (left + right) / 2;
//is the middle what we are looking for?
if (A[middle] == x) return true;
//search the half of the array that might contain x
if (A[middle] > x) { //search for x to the left
return binaryS(A, left, middle - 1, x);
} else { //search for x to the right
return binaryS(A, middle + 1, right, x);
}
}

Bob's answer is a nice binary search.
If you want to have user input (and keep your structure):
public static int recursiveBinarySearch(int[] sortedArray, int start, int end) {
if (start < end) {
int mid = (start + end) / 2;
String question = IOTools.readString("Is your number compared to "+sortedArray[mid] + " lower or higher?[You can answer: equal, lower or higher] ");
if (question.equals("higher")) {
return recursiveBinarySearch(sortedArray, mid+1, end, question);
} else if (question.equals("lower")) {
return recursiveBinarySearch(sortedArray, start, mid-1, question);
} else {
return mid;
}
}
System.out.println("Something went wrong...");
return -1;
}

Related

Integer variable stores 0 as method return value

I was trying Binary Search recursive program in Java, the algorithm seems to be perfectly fine, but the variable in which I store the result from the recursive function, is storing 0 as the value.
In the following code, I want to store the index of the element found in the variable result, but the output prints result's value as 0.
When I print the value of mid before the return statement, the value is correct. How to fix this problem??
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n;
System.out.println("Enter the number of elements in the array: ");
n = scanner.nextInt();
int arr[] = new int[n];
System.out.println("Enter the array elements (from index 0): ");
for (int i = 0; i < n; i++) {
arr[i] = scanner.nextInt();
}
int ele;
System.out.println("Enter the element to be searched: ");
ele = scanner.nextInt();
/*************************************************************************************/
int result = binarySearchRecursive(arr, 0, n - 1, ele);
System.out.println(result);
/************************************************************************************/
if (result == -1) {
System.out.println(ele + " not found");
} else {
System.out.println(ele + " found at index: " + result);
}
}
//Algorithm
public static int binarySearchRecursive(int arr[], int l, int r, int ele) {
//Check whether a single element is present
if (l == r) {
if (arr[l] == ele) {
return l;
} else {
return -1;
}
} else { //Multiple elements
int mid = (l + r) / 2;
//Check conditions
if (ele == arr[mid]) {
System.out.println("Method return 'mid' value: "+mid);
return mid;
} else if (ele < arr[mid]) {
binarySearchRecursive(arr, l, mid - 1, ele);
} else {
binarySearchRecursive(arr, mid + 1, r, ele);
}
}
return -l;
}
}
Here is the output
You should return the value of the recursive calls:
if (ele == arr[mid]) {
System.out.println("Method return 'mid' value: "+mid);
return mid;
} else if (ele < arr[mid]) {
return binarySearchRecursive(arr, l, mid - 1, ele);
} else {
return binarySearchRecursive(arr, mid + 1, r, ele);
}
You have to add return statements to the recursive function calls of binarySearchRecursive. Right now your code is always falling through to the last return statement which just returns -l => which returns 0 for binarySearchRecursive(arr, 0, n - 1, ele);
return binarySearchRecursive(arr, l, mid - 1, ele);
return binarySearchRecursive(arr, mid + 1, r, ele);

Palindrome Partitioning DP complexity issue on memorization step

I have the following problem:
Given a string s, partition s such that every substring of the
partition is a palindrome.
Return the minimum cuts needed for a palindrome partitioning of s.
I got the correct solution but I am missing an optimization step, more particularly the memorization step needed in DP.
public int minCut(String a) {
if (isValidPal(a)) {
return 0;
}
return minCut(a, 0, 0);
}
int min = Integer.MAX_VALUE;
private int minCut(String a, int cut, int index) {
// too many cuts already
if(cut >= min) return min;
// out of index
if (index >= a.length()) {
// what is left is a pal
if (isValidPal(a)) {
min = Math.min(min, cut);
return cut;
}
return Integer.MAX_VALUE;
}
int newCut = Integer.MAX_VALUE;
if (isValidPal(a.substring(0, index + 1))) {
// then cut
newCut = minCut(a.substring(index + 1), cut + 1, 0);
}
// continue either way
newCut = Math.min(minCut(a, cut, index + 1), newCut);
return newCut;
}
HashMap<String, Boolean> memo = new HashMap<>();
private boolean isValidPal(String s) {
if(memo.containsKey(s)) {
return memo.get(s);
}
boolean result = true;
for (int i = 0; i < s.length() / 2; i++) {
if (s.charAt(i) != s.charAt(s.length() - i - 1)) {
result = false;
break;
}
}
memo.put(s, result);
return result;
}
Try adding a memo to store the results of your computations , assuming your algorithm is correct this should do the optimization
Map<String, Integer> dp = new HashMap<>();
private int minCut(String a, int cut, int index) {
// too many cuts already
if(cut >= min) return min;
String key = cut + " " + index;
//test if the memo contains the answer if yes return it
if(dp.containsKey(key)) return dp.get(key);
// out of index
if (index >= a.length()) {
// what is left is a pal
if (isValidPal(a)) {
min = Math.min(min, cut);
return cut;
}
return Integer.MAX_VALUE;
}
int newCut = Integer.MAX_VALUE;
if (isValidPal(a.substring(0, index + 1))) {
// then cut
newCut = minCut(a.substring(index + 1), cut + 1, 0);
}
// continue either way
newCut = Math.min(minCut(a, cut, index + 1), newCut);
//put the computed answer in the memo table
dp.put(key, newCut);
return newCut;
}
i'm sorry but my answer was based on the fact that your code is correct , here is a working example of a min palindrom partitioning with memoization
import java.util.*;
class Main {
static HashMap<String, Integer> memo = new HashMap<>();
static String s;
static int f(int i, int j){
if(i == j) return 0;
if(isPalindrom(s.substring(i, j))) return 0;
String key = i + " " + j;
if(memo.containsKey(key)) return memo.get(key);
int ans = 999999;
for(int k = i; k < j; k++){
ans = Math.min(ans, f(i, k) + f(k + 1, j) + 1);
}
memo.put(key, ans);
return ans;
}
static boolean isPalindrom(String s){
return s.equals(new StringBuilder(s).reverse().toString());
}
public static void main(String[] args) {
s = "aaka";
System.out.println(f(0, s.length()));
}
}

Find Kth min elem by randomized pivot method. Some weird bug

I try to use "randomized pivot" method to find the Kth min elem among given array.
[The code]
public class FindKthMin {
// Find the Kth min elem by randomized pivot.
private static void exchange (int[] givenArray, int firstIndex, int secondIndex) {
int tempElem = givenArray[firstIndex];
givenArray[firstIndex] = givenArray[secondIndex];
givenArray[secondIndex] = tempElem;
}
private static int partition (int[] givenArray, int start, int end, int pivotIndex) {
// Debug:
//System.out.println("debug: start = " + start);
//System.out.println(">> end = " + end);
//System.out.println(">> pivotIndex = " + pivotIndex);
int pivot = givenArray[pivotIndex];
int left = start - 1;
int right = end;
boolean hasDone = false;
while (!hasDone) {
while (!hasDone) {
left ++;
if (left == right) {
hasDone = true;
break;
}
if (givenArray[left] >= pivot) {
// Exchange givenArray[left] and the givenArray[right].
exchange(givenArray, left, right);
break;
}
}
while (!hasDone) {
right --;
if (left == right) {
hasDone = true;
break;
}
if (givenArray[right] < pivot) {
// Exchange the givenArray[right] and the givenArray[left].
exchange(givenArray, right, left);
break;
}
}
}
givenArray[right] = pivot;
// Debug:
//System.out.println(">> split = " + right);
//System.out.println();
return right;
}
private static int findKthMin_RanP_Helper (int[] givenArray, int start, int end, int k) {
if (start > end) return -1;
// Generate a random num in the range[start, end].
int rand = (int)(start + Math.random() * (end - start + 1));
// Using this random num as the pivot index to partition the array in the current scope.
int split = partition(givenArray, start, end, rand);
if (k == split + 1) return givenArray[split];
else if (k < split + 1) return findKthMin_RanP_Helper(givenArray, start, split - 1, k);
else return findKthMin_RanP_Helper(givenArray, split + 1, end, k);
}
public static int findKthMin_RanP (int[] givenArray, int k) {
int size = givenArray.length;
if (k < 1 || k > size) return -1;
return findKthMin_RanP_Helper(givenArray, 0, size - 1, k);
}
// Main method to test.
public static void main (String[] args) {
// Test data: {8, 9, 5, 2, 8, 4}.
int[] givenArray = {8, 9, 5, 2, 8, 4};
// Test finding the Kth min elem by randomized pivot method.
System.out.println("Test finding the Kth min elem by randomized pivot method, rest = " + findKthMin_RanP(givenArray, 1));
}
}
But the result is unstable, sometimes right and sometimes wrong.
Please have a look at the 5th row of findKthMin_RanP_Helper method:
If I change this int split = partition(givenArray, start, end, rand); to int split = partition(givenArray, start, end, end);, the result is always correct. I really can not find what's wrong with this.
EDIT:
The problem comes from the "partition", the new partition should like this:
private static int partition_second_version (int[] givenArray, int start, int end, int pivotIndex) {
int pivot = givenArray[pivotIndex];
int left = start;
int right = end;
while (left <= right) {
while (givenArray[left] < pivot) left ++;
while (givenArray[right] > pivot) right --;
if (left <= right) {
// Exchange givenArray[left] and givenArray[right].
exchange(givenArray, left, right);
left ++;
right --;
}
}
return left;
}
And the findKthMin_RanP_Helper should be changed like this:
private static int findKthMin_RanP_Helper (int[] givenArray, int start, int end, int k) {
if (start > end) return -1;
// Generate a random num in the range[start, end].
int rand = start + (int)(Math.random() * ((end - start) + 1));
// Using this random num as the pivot index to partition the array in the current scope.
int split = partition_second_version (givenArray, start, end, rand);
if (k == split) return givenArray[split - 1];
else if (k < split) return findKthMin_RanP_Helper(givenArray, start, split - 1, k);
else return findKthMin_RanP_Helper(givenArray, split, end, k);
}
Your partition routine could be simplified...
private static int partition(int[] givenArray, int start, int end, int pivotIndex) {
final int pivot = givenArray[pivotIndex];
int left = start;
int right = end;
while (left < right) {
while (left < givenArray.length && givenArray[left] <= pivot) {
left++;
}
while (right > -1 && givenArray[right] > pivot) {
right--;
}
if (left >= right) {
break;
}
exchange(givenArray, right, left);
}
return right;
}
The one bug I see in your code is your partition routine. In the first exchange call, it is not guaranteed that the right index will always point to a value which is < pivot.

Finding Max value in an array using recursion

For one of the questions i was asked to solve, I found the max value of an array using a for loop, so i tried to find it using recursion and this is what I came up with:
public static int findMax(int[] a, int head, int last) {
int max = 0;
if (head == last) {
return a[head];
} else if (a[head] < a[last]) {
return findMax(a, head + 1, last);
} else {
return a[head];
}
}
So it works fine and gets the max value, but my question is : is it ok to have for the base case return a[head] and for the case when the value at the head is > the value at last?
You could just as easily do it with only one counter, just the index of the value you want to compare this time:
public static int findMax(int[] a, int index) {
if (index > 0) {
return Math.max(a[index], findMax(a, index-1))
} else {
return a[0];
}
}
This much better shows what is going on, and uses the default "recursion" layout, e.g. with a common base step. Initial call is by doing findMax(a, a.length-1).
It's actually much simpler than that. The base case is if you've reached the end of the array (the 'else' part of the ternary control block below). Otherwise you return the max of the current and the recursive call.
public static int findMax(int[] a) {
return findMax(a, 0);
}
private static int findMax(int[] a, int i) {
return i < a.length
? Math.max(a[i], findMax(a, i + 1))
: Integer.MIN_VALUE;
}
At each element, you return the larger of the current element, and all of the elements with a greater index. Integer.MIN_VALUE will be returned only on empty arrays. This runs in linear time.
I would solve this by dividing the array in to the half on each recursive call.
findMax(int[] data, int a, int b)
where a and b are array indices.
The stop condition is when b - a <= 1, then they are neighbours and the max is max(a,b);
The initial call:
findMax(int[] data, int 0, data.length -1);
This reduces the maximum recursion depth from N to log2(N).
But the search effort still stays O(N).
This would result in
int findMax(int[] data, int a, int b) {
if (b - a <= 1) {
return Math.max(data[a], data[b]);
} else {
int mid = (a+b) /2; // this can overflow for values near Integer.Max: can be solved by a + (b-a) / 2;
int leftMax = findMax(a, mid);
int rightMax = findMax(mid +1, b);
return Math.max(leftMax, rightMax);
}
}
I came across this thread and it helped me a lot. Attached is my complete code in both recursion and divide&conquer cases.
The run time for divide&conquer is slightly better than recursion.
//use divide and conquer.
public int findMaxDivideConquer(int[] arr){
return findMaxDivideConquerHelper(arr, 0, arr.length-1);
}
private int findMaxDivideConquerHelper(int[] arr, int start, int end){
//base case
if(end - start <= 1) return Math.max(arr[start], arr[end]);
//divide
int mid = start + ( end - start )/2;
int leftMax =findMaxDivideConquerHelper(arr, start, mid);
int rightMax =findMaxDivideConquerHelper(arr, mid+1, end);
//conquer
return Math.max( leftMax, rightMax );
}
// use recursion. return the max of the current and recursive call
public int findMaxRec(int[] arr){
return findMaxRec(arr, 0);
}
private int findMaxRec(int[] arr, int i){
if (i == arr.length) {
return Integer.MIN_VALUE;
}
return Math.max(arr[i], findMaxRec(arr, i+1));
}
What about this one ?
public static int maxElement(int[] a, int index, int max) {
int largest = max;
while (index < a.length-1) {
//If current is the first element then override largest
if (index == 0) {
largest = a[0];
}
if (largest < a[index+1]) {
largest = a[index+1];
System.out.println("New Largest : " + largest); //Just to track the change in largest value
}
maxElement(a,index+1,largest);
}
return largest;
}
I know its an old Thread, but maybe this helps!
public static int max(int[] a, int n) {
if(n < 0) {
return Integer.MIN_VALUE;
}
return Math.max(a[n-1], max(a, n - 2));
}
class Test
{
int high;
int arr[];
int n;
Test()
{
n=5;
arr = new int[n];
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
arr[3] = 40;
arr[4] = 50;
high = arr[0];
}
public static void main(String[] args)
{
Test t = new Test();
t.findHigh(0);
t.printHigh();
}
public void printHigh()
{
System.out.println("highest = "+high);
}
public void findHigh(int i)
{
if(i > n-1)
{
return;
}
if(arr[i] > high)
{
high = arr[i];
}
findHigh(i+1);
return;
}
}
You can do it recursively as follows.
Recurrent relation it something like this.
f(a,n) = a[n] if n == size
= f(a,n+1) if n != size
Implementation is as follows.
private static int getMaxRecursive(int[] arr,int pos) {
if(pos == (arr.length-1)) {
return arr[pos];
} else {
return Math.max(arr[pos], getMaxRecursive(arr, pos+1));
}
}
and call will look like this
int maxElement = getMaxRecursive(arr,0);
its not okay!
your code will not find the maximum element in the array, it will only return the element that has a higher value than the elements next to it, to solve this problem,the maximum value element in the range can be passed as argument for the recursive method.
private static int findMax(int[] a, int head, int last,int max) {
if(last == head) {
return max;
}
else if (a[head] > a[last]) {
max = a[head];
return findMax(a, head, last - 1, max);
} else {
max = a[last];
return findMax(a, head + 1, last, max);
}
}
Optimized solution
public class Test1 {
public static int findMax(int[] a, int head, int last) {
int max = 0, max1 = 0;
if (head == last) {
return a[head];
} else if (a[head] < a[last]) {
max = findMax(a, head + 1, last);
} else
max = findMax(a, head, last - 1);
if (max >= max1) {
max1 = max;
}
return max1;
}
public static void main(String[] args) {
int arr[] = {1001, 0, 2, 1002, 2500, 3, 1000, 7, 5, 100};
int i = findMax(arr, 0, 9);
System.out.println(i);
}
}
Thanks #Robert Columbia for the suggestion!
Update: This following function is going to recursively start from index 0 and it will keep adding to this index value till it's equal to the Length of the array, if it's more we should stop and return 0. Once we're doing that, we need to get the max of every two items in the array so, for example:
A = [1 , 2 , 3 ];
A[0] ( 1 ) vs A[1] ( 2 ) = 2
A[1] ( 2 ) vs A[2] ( 3 ) = 3
Max(2,3) = 3 ( The answer )
public int GetMax(int [] A, int index) {
index += 1;
if (index >= A.Length) return 0;
return Math.Max(A[index], GetMax(A, index + 1));
}
static int maximumOFArray(int[] array,int n) {
int max=Integer.MIN_VALUE;
if(n==1) return array[0];
else
max=maximumOFArray(array, --n);
max= max>array[n] ? max : array[n];
return max;
}
private static int getMax(int [] arr, int idx) {
if (idx==arr.length-1 ) return arr[idx];
return Math.max(arr[idx], getMax (arr,idx+1 ));
}
public class FindMaxArrayNumber {
public static int findByIteration(int[] array) {
int max = array[0];
for (int j : array) {
max = Math.max(j, max);
}
return max;
}
public static int findByRecursion(int[] array, int index) {
return index > 0
? Math.max(array[index], findByRecursion(array, index - 1))
: array[0];
}
public static void main(String[] args) {
int[] array = new int[]{1, 2, 12, 3, 4, 5, 6};
int maxNumberByIteration = findByIteration(array);
int maxNumberByRecursion = findByRecursion(array, array.length - 1);
System.out.println("maxNumberByIteration: " + maxNumberByIteration);
System.out.println("maxNumberByRecursion: " + maxNumberByRecursion);
// Outputs:
// maxNumberByIteration: 12
// maxNumberByRecursion: 12
}
}
int maximum = getMaxValue ( arr[arr.length - 1 ], arr, arr.length - 1 );
public static int getMaxValue ( int max, int arr[], int index )
{
if ( index < 0 )
return max;
if ( max < arr[index] )
max = arr[index];
return getMaxValue ( max, arr, index - 1 );
}
I felt that using a tracker for current maximum value would be good.

How to use recursion in creating a binary search algorithm

I have been using my time off university to practice Java through coding algorithms. One of the algorithms I coded was the binary search:
public class BinarySearch {
private static int list[] = {3, 6, 7, 8, 9, 10};
public static void main(String[] args) {
BinarySearch b = new BinarySearch();
b.binarySearch(list);
}
public void binarySearch(int[] args) {
System.out.println("Binary search.");
int upperBound = args.length;
int lowerBound = 1;
int midpoint = (upperBound + lowerBound) / 2;
int difference = upperBound - lowerBound;
int search = 7;
for (int i = 0; i < args.length; i++) {
if (search < args[midpoint - 1] && difference != 1) {
upperBound = midpoint - 1;
midpoint = upperBound / 2;
} else if (search > args[midpoint - 1] && difference != 1) {
lowerBound = midpoint + 1;
midpoint = (lowerBound + upperBound) / 2;
} else if (search == args[midpoint - 1]) {
midpoint = midpoint - 1;
System.out.println("We found " + search + " at position " + midpoint + " in the list.");
i = args.length;
} else {
System.out.println("We couldn't find " + search + " in the list.");
i = args.length;
}
}
}
}
I really want to be able to write a much cleaner and efficient binary search algorithm, an alternative to what I've coded. I have seen examples of how recursion is used such as when doing factorial with numbers which I understand. However when coding something of this complexity I am confused on how to use it to my advantage. Therefore my question is how do I apply recursion when coding a binary search algorithm. And if you have any tips for me to perfect my recursion skills even if it has to be something that doesn't regard to binary search then please feel free to post.
If you really want to use recursion, this should do it.
public static int binarySearch(int[] a, int target) {
return binarySearch(a, 0, a.length-1, target);
}
public static int binarySearch(int[] a, int start, int end, int target) {
int middle = (start + end) / 2;
if(end < start) {
return -1;
}
if(target==a[middle]) {
return middle;
} else if(target<a[middle]) {
return binarySearch(a, start, middle - 1, target);
} else {
return binarySearch(a, middle + 1, end, target);
}
}
Here is an easier way of doing binary search:
public static int binarySearch(int intToSearch, int[] sortedArray) {
int lower = 0;
int upper = sortedArray.length - 1;
while (lower <= upper) {
int mid = lower + (upper - lower) / 2;
if(intToSearch < sortedArray[mid])
upper = mid - 1;
else if (intToSearch > sortedArray[mid])
lower = mid + 1;
else
return mid;
}
return -1; // Returns -1 if no match is found
}
Following is a code sample extracted from here.
public class BinarySearch {
public boolean find(int[] sortedValues, int value) {
return search(sortedValues, value, 0, sortedValues.length - 1);
}
private boolean search(int[] sorted, int value, int leftIndex, int rightIndex) {
// 1. index check
if (leftIndex > rightIndex) {
return false;
}
// 2. middle index
int middle = (rightIndex + leftIndex) / 2;
// 3. recursive invoke
if (sorted[middle] > value) {
return search(sorted, value, leftIndex, middle - 1);
} else if (sorted[middle] < value) {
return search(sorted, value, middle + 1, rightIndex);
} else {
return true;
}
}
}
You can find implementations of the below test cases against the above binary search implementation as well in the reference link.
1. shouldReturnFalseIfArrayIsEmpty()
2. shouldReturnFalseIfNotFoundInSortedOddArray()
3. shouldReturnFalseIfNotFoundInSortedEvenArray()
4. shouldReturnTrueIfFoundAsFirstInSortedArray()
5. shouldReturnTrueIfFoundAtEndInSortedArray()
6. shouldReturnTrueIfFoundInMiddleInSortedArray()
7. shouldReturnTrueIfFoundAnywhereInSortedArray()
8. shouldReturnFalseIfNotFoundInSortedArray()
A possible example is :
// need extra "helper" method, feed in params
public int binarySearch(int[] a, int x) {
return binarySearch(a, x, 0, a.length - 1);
}
// need extra low and high parameters
private int binarySearch(int[ ] a, int x,
int low, int high) {
if (low > high) return -1;
int mid = (low + high)/2;
if (a[mid] == x) return mid;
else if (a[mid] < x)
return binarySearch(a, x, mid+1, high);
else // last possibility: a[mid] > x
return binarySearch(a, x, low, mid-1);
}
Here you can check in C Binary Search, With and Without Recursion
Source : http://www.cs.utsa.edu/~wagner/CS3343/recursion/binsearch.html
Here is a algorithm which should get you going. Let your method signature be:
public boolean binarysearchRecursion(Array, begin_index,end_index, search_element)
Check if your begin_index > end_index if YES then return false.
Calculate mid_element for your input array.
Check if your search_element is equal to this mid_element. if YES return true
If mid_element > search_element Call your method with for range 0 - mid
If mid_element < search_element Call your method with for range mid+1 - Length_of_Array
Also as #DwB said in his comment you are better using loop to get things done. Some problems are recursive in nature(Like binary tree problems). But this one is not one of them.
This is another way of doing recursion:
int[] n = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
#Test
public void testRecursiveSolution() {
Assert.assertEquals(0, recursiveBinarySearch(1,n));
Assert.assertEquals(15, recursiveBinarySearch(16,n));
Assert.assertEquals(14, recursiveBinarySearch(15,n));
Assert.assertEquals(13, recursiveBinarySearch(14,n));
Assert.assertEquals(12, recursiveBinarySearch(13,n));
Assert.assertEquals(11, recursiveBinarySearch(12,n));
Assert.assertEquals(10, recursiveBinarySearch(11,n));
Assert.assertEquals(9, recursiveBinarySearch(10,n));
Assert.assertEquals(-1, recursiveBinarySearch(100,n));
}
private int recursiveBinarySearch(int n, int[] array) {
if(array.length==1) {
if(array[0]==n) {
return 0;
} else {
return -1;
}
} else {
int mid = (array.length-1)/2;
if(array[mid]==n) {
return mid;
} else if(array[mid]>n) {
return recursiveBinarySearch(n, Arrays.copyOfRange(array, 0, mid));
} else {
int returnIndex = recursiveBinarySearch(n, Arrays.copyOfRange(array, mid+1, array.length));
if(returnIndex>=0) {
return returnIndex+mid+1;
} else {
return returnIndex;
}
}
}
}
While it doesn't return the index, this at least returns the idea of 'yes' or 'no' that something is in the collection:
public static boolean recursive(int[] input, int valueToFind) {
if (input.length == 0) {
return false;
}
int mid = input.length / 2;
if (input[mid] == valueToFind) {
return true;
} else if (input[mid] > valueToFind) {
int[] smallerInput = Arrays.copyOfRange(input, 0, mid);
return recursive(smallerInput, valueToFind);
} else if (input[mid] < valueToFind) {
int[] smallerInput = Arrays.copyOfRange(input, mid+1, input.length);
return recursive(smallerInput, valueToFind);
}
return false;
}
A recursion BinarySearch with break conditions in case you can not find the value you are looking for
public interface Searcher{
public int search(int [] data, int target, int low, int high);
}
The Implementation
public class BinarySearch implements Searcher {
public int search(int[] data, int target, int low, int high) {
//The return variable
int retorno = -1;
if(low > high) return retorno;
int middle = (high + low)/2;
if(target == data[middle]){
retorno = data[middle];
}else if(target < data[middle] && (middle - 1 != high)){
//the (middle - 1 != high) avoids beeing locked inside a never ending recursion loop
retorno = search(data, target, low, middle - 1);
}else if(target > data[middle] && (middle - 1 != low)){
//the (middle - 1 != low) avoids beeing locked inside a never ending recursion loop
retorno = search(data, target, middle - 1, high);
}else if(middle - 1 == low || middle - 1 == high){
//Break condition if you can not find the desired balue
retorno = -1;
}
return retorno;
}
}

Categories

Resources