1

I have tried implementing the divide and conquer technique of binary search using recursion. The code for it can be seen below. I think when the program is run, I'm getting stack overflow. If anyone does manage to find a solution, I would greatly appreciate a reason for why this happens.

public class binarySearch{
    public static void main(String[] arguments){
        int[] array = new int[]{1,2,3,4,5,6,7,8,9};
        int findNum = binSearch(array, 9, 0, array.length-1);
    }

    public static int binSearch(int[] array, int searchNum, int left, int right){
        int foundIndex = 0;
        boolean found = false;
        int mid = (right+left)/2;
        if(array[mid] == searchNum){
            found = true;
            foundIndex = mid;
        }
        else if(array[mid] > searchNum){
            right = mid;
            binSearch(array, searchNum, left, right);
        }
        else if(array[mid] < searchNum){
            left = mid;
            binSearch(array, searchNum, left, right);
        }

        if(found = true){
            return foundIndex;
        }
        else{
            return -1;
        }
    }
}
Scott Hunter
  • 48,888
  • 12
  • 60
  • 101

3 Answers3

2

All of the solution posted so far has a integer overflow problem while calculating mid.The same bug lurked in JDK for more than 20 years https://ai.googleblog.com/2006/06/extra-extra-read-all-about-it-nearly.html

int binarySearch(int arr[],int searchNum,int left, int right)
    {
        if (right >= left) {
            int mid = (left+right)>>>1; 
            if (arr[mid] == searchNum)
                return mid;
            if (arr[mid] > searchNum)
                return binarySearch(arr, left,mid - 1, searchNum);

            return binarySearch(arr, mid + 1, right, searchNum);
        }
        return -1;
    }
Debapriya Biswas
  • 1,079
  • 11
  • 23
0

You're calling binSearch but never returning the value of that call. I think you're trying to treat found as a static variable in C, but there's no such thing in Java. Even if you modify it in another stackframe, the value in your current stackframe will still stay false.

A better way would be to use tail-recursion and directly return the result.

public static int binSearch(int[] array, int searchNum, int left, int right){
    if (left == right) 
        return -1;
    int mid = (right + left) >>> 1;
    if(array[mid] == searchNum) 
        return mid;
    else if(array[mid] > searchNum) 
        return binSearch(array, searchNum, left, mid);
    else 
        return binSearch(array, searchNum, mid + 1, right);
}

And you can invoke the method like this (right should be exclusive)

int findNum = binSearch(array, -1, 0, array.length);

EDIT: After reading the answer by Debapriya Biswas, I changed the line int mid = (right + left) / 2; to int mid = (right + left) >>> 1; to avoid failing when right + left is greater than the max value of int.

user
  • 7,435
  • 3
  • 14
  • 44
0

Your implementation logic is wrong and thus your code runs into infinite recursion. The correct code should be as follows -

public class binarySearch{
    public static void main(String[] arguments){
        int[] array = new int[]{1,2,3,4,5,6,7,8,9};
        int findNum = binSearch(array, 9, 0, array.length-1);
    }

    public static int binSearch(int[] array, int searchNum, int left, int right){
        if(left>right)
            return -1; // We have now tried the full binary search and unable to find the element
        int mid = (right+left)/2;
        if(array[mid] == searchNum){
             return mid;
        }
        else if(array[mid] > searchNum)
            return binSearch(array, searchNum, left, mid-1); // <-- Here you were calling 
                                                             //binSearch(array, searchNum, left, right); which made your code go into infinite recursion

        else if(array[mid] < searchNum)
            return binSearch(array, searchNum, mid+1, right); //<-- you were calling 
                                                              //binSearch(array, searchNum, left, right); which made your code go into infinite recursion           
    }
}

The above code will return the index if the element is found in the array else it will return -1. You would also notice that I am directly returning the recursive call like - return binSearch(array, searchNum, mid+1, right);and not just calling like - binSearch(array, searchNum, left, right);

Hope this helps !

Abhishek Bhagate
  • 5,583
  • 3
  • 15
  • 32