Logo

Programming-Idioms

  • Lisp
  • Go
  • JS
  • Pascal

Idiom #124 Binary search for a value in sorted array

Write the function binarySearch which returns the index of an element having the value x in the sorted array a, or -1 if no such element exists.

func binarySearch(a []T, x T) int {
	imin, imax := 0, len(a)-1
	for imin <= imax {
		imid := imin + (imax-imin) / 2
		switch {
		case a[imid] == x:
			return imid
		case a[imid] < x:
			imin = imid + 1
		default:
			imax = imid - 1
		}
	}
	return -1
}

Iterative algorithm.
It does not always return the smallest possible index.
You may implement this for any element type T that is ordered.
import "sort"
func binarySearch(a []T, x T) int {
	f := func(i int) bool { return a[i] >= x }
	i := sort.Search(len(a), f)
	if i < len(a) && a[i] == x {
		return i
	}
	return -1
}

This uses the standard library generic-purpose sort.Search. Read the documentation carefully.
It returns the smallest matching index.
import "sort"
func binarySearch(a []int, x int) int {
	i := sort.SearchInts(a, x)
	if i < len(a) && a[i] == x {
		return i
	}
	return -1
}

If the elements have type int, then use standard library's sort.SearchInts.
It returns the smallest matching index.
import "slices"
func binarySearch(a []T, x T) int {
	if i, ok := slices.BinarySearch(a, x); ok {
		return i
	} else {
		return -1
	}
}

This generic func slices.BinarySearch works for all slice types
function binarySearch(a, x, i = 0) {
  if (a.length === 0) return -1
  const half = (a.length / 2) | 0
  return (a[half] === x) ?
    i + half :
    (a[half] > x) ?
    binarySearch(a.slice(0, half), x, i) :
    binarySearch(a.slice(half + 1), x, half + i + 1)
}

x | 0 removes the bit of x after the decimal.
This would be easier if JavaScript had more builtins for list processing.
function BinarySearch(X: Integer; A: Array of Integer): Integer;
var
  L, R, I, Cur, answer: Integer;
  isIt :boolean;
begin
  isIt := false;
  answer := -1;
  if Length(A) = 0 then Exit;
  L := Low(A);
  R := High(A);
  while ((L <= R) AND (isIt = false)) do
  begin
    I := L + ((R - L) div 2); 
    Cur := A[I];
    if (X = Cur) then begin
	answer := i;  {cur;}
	isIt := true;
    end;
    if (X > Cur) then
       L := I + 1
    else
      R := I - 1
  end;
  BinarySearch := answer;
end;

the index of the array is i;
Cur is the value of A[i]; but we
search the index i
function binarySearch (x: integer; a: array of integer): integer;
var  L, R, M: integer;  // left, right, middle
begin
  if Length(a)=0 then Exit(-1);
  L := Low (a);
  R := High(a);
  while (L <= R) do begin
    M := (L + R) div 2;
    if (x = a[M]) then Exit(M);  // found x in a
    if (x > a[M]) 
    then L := Succ(M)
    else R := Pred(M);
  end;
  Exit(-1) // did not found x in a
end;
#include <vector>
template<typename T>
int binarySearch(const std::vector<T> &a, const T &x)
{
    if(a.size() == 0) return -1;

    size_t lower = 0;
    size_t upper = a.size() - 1;

    while(lower <= upper)
    {
        auto mid = lower + (upper-lower) / 2;

        if(x == a[mid])
        {
            return (int)mid;
        }
        else if(x > a[mid])
        {
            lower = mid + 1;
        }
        else
        {
            upper = mid - 1;
        }
    }

    return -1;
}

Check for an empty vector up front, otherwise size() will return an unsigned 0, and subtracting 1 will be a big number!

New implementation...
< >
programming-idioms.org