Binary Search analysis
Pseudocode:
function binarySearch(a, value, left, right)
    if right < left
        return not found
    mid := floor((right-left)/2)+left
    if a[mid] = value
        return mid
    if value < a[mid]
        return binarySearch(a, value, left, mid-1)
    else
        return binarySearch(a, value, mid+1, right)
Note that mid is defined as
floor((right-left)/2+left
cause if the array is indexed, say, form 4 to 10, the mid is actually
(high - low)/2 + offset
A binary search halves the number of items to check with each iteration, so locating an item (or determining its absence) takes logarithmic time.
A sketch of the proof for N being even is the following: we define \( C(N) \) as the number of compares needed to locate the key in an array of N elements. We start with
\[C(0) = 0 \\
C(1) = 1 \\
C(N) \leq C(N/2) + 1 \\
\]
the number of compares for N is at most N/2 + 1: 1 to check for equality and decide for the left half or the right half. Applying the same logic, we obtain:
\[\begin{align}
C(N/2) + 1 & \leq C(N/4) + 1 + 1 \\
& \leq C(N/8) + 1 + 1 + 1 \\
& \leq C(N/16) + 1 + 1 + 1 + 1 \\
& \leq C(N/N) + 1 + 1 + 1 + 1 + … + 1 \\
& = 1 + \log N \\
\end{align}
\]
At that point we stop since C(1) = 1, giving us the number of times we had to halve the space search to get to N.
Implementation in Python: recursive
def bs(n, l):
    if len(l) < 1:
        return 'not found'
    mid = len(l)/2
    if l[mid] == n:
        return l[mid]
    elif n < l[mid]:
        return bs(n, l[:mid])
    else:
        return bs(n, l[mid+1:])
iterative:
def ibs(n, l):
    imin = min(l)
    imax = max(l)
    while imax > imin:
        imid = (imax - imin)/2 + imin
        if l[imid] == n:
            return l[imid]
        elif n < l[imid]:
            imax = imid - 1
        else:
            imin = imid + 1
            return 'not found'