Java – My basic binary search method does not work with a specific value in an int array in Java

My basic binary search method does not work with a specific value in an int array in Java… here is a solution to the problem.

My basic binary search method does not work with a specific value in an int array in Java

I am a Java beginner and here is a small program that can output the index of the int value searched in the int array. Here is the code

public static void main(String[] args) {

int rank =findNumber(7, new int[]{2, 4, 7, 10, 11, 45, 50, 59, 60, 66, 69, 70, 79});
    System.out.println("Your number's index is " + rank);

}

public static int findNumber(int key, int... numbers) {
    int low = 0;
    int high = numbers.length - 1;
    int mid = (low + high) / 2;
    int rank = 0;
    for (int i = low; i < high; i++) {
        if (key < numbers[mid]) {
            high = mid;
            mid = (low + high) / 2;
        } else if (key > numbers[mid]) {
            low = mid;
            mid = (low + high) / 2;
        } else {
            rank = mid;
            return rank;
        }
    }
    return rank;
}

The problem is that it works for all numbers in the array, except 7. I tried to find it by debugging, but to no avail.

Can anyone tell me what the problem is?

Solution

The problem is that even though you are changing low and high, the loop depends on the variable i which only changes by incrementing at the end of each iteration of the loop. However, the termination condition for a binary lookup should be low >= high. Your current loop condition, I < High has nothing to do with the relationship between low and high, which can cause the loop to end prematurely or continue when the binary search has ended.

What I recommend doing is initializing low in the for loop, changing the termination condition to low <= high, and formulating the update sequence mid = (low + high)/2 because unless you find the number, you do this after each iteration of the for loop. However, at this point the loop terminates the index of the number found. This is what it looks like

public static int findNumber(int key, int... numbers) {
    int high = numbers.length - 1;
    int mid = (0 + high) / 2; replaced low with 0 here
    int rank = 0;
    for (int low = 0; low <= high; mid = (low + high) / 2) {
        if (key < numbers[mid]) {
            high = mid - 1;
        } else if (key > numbers[mid]) {
            low = mid + 1;
        } else {
            rank = mid;
            return rank;
        }
    }
    return rank;
}

EDIT: So after some testing, I realized another mistake is how do you update low and high in your method. Previously, when updating these variables, you were just doing high = mid and low = mid but this is risky because by doing this, you basically still keep numbers[mid] in range that will be evaluated in the next iteration of the loop. This number, numbers[mid], should be omitted from the range because the key is either less than, greater than, or equal to numbers[mid]. So one solution is to update low and high by low = mid + 1 and high = mid - 1

Related Problems and Solutions