2

Hi,

what is the index of the search key if we search for 24 in the following array using binary search.

array = [10,20,21,24,24,24,24,24,30,40,45]

I have a doubt regarding binary search that how does it works if a array has duplicate values.Can anybody clarify...

3
  • 2
    Are you asking, 'if i were to implement a binary search and was given this array and asked to find the index of 24, what should I return?' or are you asking 'if I ran this array through someone else's implementation of a binary search, which I am too lazy to do, what would the return value be?' Commented Mar 14, 2012 at 13:08
  • 2
    You can tell those both scenarios if possible..that would be appreciated... Commented Mar 14, 2012 at 13:11
  • 1
    Obviously result will be array[5]. Commented Mar 14, 2012 at 13:27

5 Answers 5

8

The array you proposed has the target value in the middle index, and in the most efficient implementations will return this value before the first level of recursion. This implementation would return '5' (the middle index).

To understand the algorithm, just step through the code in a debugger.

public class BinarySearch {
    public static int binarySearch(int[] array, int value, int left, int right) {
          if (left > right)
                return -1;
          int middle = left + (right-left) / 2;
          if (array[middle] == value)
                return middle;
          else if (array[middle] > value)
                return binarySearch(array, value, left, middle - 1);
          else
                return binarySearch(array, value, middle + 1, right);           
    }

    public static void main(String[] args) {
        int[] data = new int[] {10,20,21,24,24,24,24,24,30,40,45};

        System.out.println(binarySearch(data, 24, 0, data.length - 1));
    }
}
Sign up to request clarification or add additional context in comments.

Comments

4

As pointed out by @Pleepleus it will return the index 5 from the first level of recursion itself. However I would like to point out few things about binary search :

  1. Instead of using mid = (left + right)/2 , use mid = left + (right-left)/2
  2. If you want to search for lower_bound or upper_bound of an element use the following algorithms:

    binLowerBound(a, lo, hi, x)
      if (lo > hi)
        return lo;
    
      mid = lo +  (hi - lo) / 2;
      if (a[mid] == x)
        return binLowerBound(a, lo, mid-1, x);
      else if (a[mid] > x)
        return binLowerBound(a, lo, mid-1, x);
      else
        return binLowerBound(a, mid+1, hi, x);
    
    binHigherBound(a, lo, hi, x)
      if (lo > hi)
        return lo;
      mid = lo + (hi - lo) / 2;
      if (a[mid] == x)
        return binHigherBound(a, mid+1, hi, x);
      else if (a[mid] > x)
        return binHigherBound(a, lo, mid-1, x);
      else
        return binHigherBound(a, mid+1, hi, x);
    

1 Comment

brilliant! tested only lower bound though!
2

For the sake of completeness here's an example in typescript, non-recursive version (binary operators are used to enforce operations on integers rather than floating-point arithmetic) Example is easily convertible to other C-like languages:

function binarySearch(array: number[], query: number): [number, number] {
    let from: number;
    let till: number;

    let mid = 0 | 0;
    let min = 0 | 0;
    let max = array.length - 1 | 0;

    while (min < max) {
        mid = (min + max) >>> 1;

        if (array[mid] < query) {
            min = mid + 1 | 0;
        } else {
            max = mid - 1 | 0;
        }
    }

    mid = min;
    min--;
    max++;

    from = array[mid] < query ? (array[max] === query ? max : mid) : (array[mid] === query ? mid : min);

    min = 0 | 0;
    max = array.length - 1 | 0;

    while (min < max) {
        mid = (min + max) >>> 1;

        if (query < array[mid]) {
            max = mid - 1 | 0;
        } else {
            min = mid + 1 | 0;
        }
    }

    mid = min;
    min--;
    max++;

    till = array[mid] > query ? (array[min] === query ? min : mid) : (array[mid] === query ? mid : max);

    return [from, till];
}

Here's how it can be used:

let array = [1, 3, 3, 3, 5, 5, 5, 5, 5, 5, 7];

console.log(binarySearch(array, 0)); // Gives [ -1,  0 ] <= No value found, note that resulting range covers area beyond array boundaries
console.log(binarySearch(array, 1)); // Gives [  0,  0 ] <= Singular range (only one value found)
console.log(binarySearch(array, 2)); // Gives [  0,  1 ] <= Queried value not found, however the range covers argument value
console.log(binarySearch(array, 3)); // Gives [  1,  3 ] <= Multiple values found
console.log(binarySearch(array, 4)); // Gives [  3,  4 ] <= Queried value not found, however the range covers argument value
console.log(binarySearch(array, 5)); // Gives [  4,  9 ] <= Multiple values found
console.log(binarySearch(array, 6)); // Gives [  9, 10 ] <= Queried value not found, however the range covers argument value
console.log(binarySearch(array, 7)); // Gives [ 10, 10 ] <= Singular range (only one value found)
console.log(binarySearch(array, 8)); // Gives [ 10, 11 ] <= No value found, note that resulting range covers area beyond array boundaries

Comments

0
public class a{
    public static int binarySearch(int[] array, int value, int left, int right) {
          if (left > right)
                return -1;
          int middle = (left + right) / 2;
          if (array[middle] == value)
        {
            if(array[middle-1]<array[middle])
                return middle;
                 //return binarySearch(array, value, left, middle - 1);
                 else
                return binarySearch(array, value, left, middle - 1);
        }
          else if (array[middle] > value)
                return binarySearch(array, value, left, middle - 1);
          else
                return binarySearch(array, value, middle + 1, right);           
    }
public static int binarySearch1(int[] array, int value, int left, int right) {
          if (left > right)
                return -1;
          int middle = (left + right) / 2;
          if (array[middle] == value)
        {
            if(array[middle]<array[middle+1])
                return middle; 
                 else

                    return binarySearch1(array, value, middle + 1, right);           
        }
          else if (array[middle] > value)
                return binarySearch1(array, value, left, middle - 1);
          else
                return binarySearch1(array, value, middle + 1, right);           
    }

    public static void main(String[] args) {
        int[] data = new int[] {10,20,21,24,24,24,24,24,30,40,45};


        System.out.println(binarySearch(data, 24, 0, data.length - 1));     //First Index
        System.out.println(binarySearch1(data, 24, 0, data.length - 1));    //Last Index
    }
}

Comments

0

It works in both unique and non-unique array.

def binary_search(n,s):
  search = s
  if len(n) < 1:
    return "{} is not in array".format(search)
  if len(n) == 1 and n[0] != s:
    return "{} is not in array".format(search)
  
  mid = len(n)//2
  ele = n[mid]
  if search == ele:
    return "{} is in array".format(search)
  elif search > ele:
    return binary_search(n[mid:],search)
  else:
    return binary_search(n[:mid],search)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.