Algorithms and OOD (CSC 207 2014F) : Outlines

Outline 23: Linear and Binary Search


Held: Tuesday, 7 October 2014

Back to Outline 22 - Analyzing Algorithms. On to Outline 24 - Reasoning About Loops with Loop Invariants.

Summary

We consider two basic search mechanisms, linear search and binary search. Along the way, we also consider the design of reusable solutions in Java, relying on generics and functions as parameters to achieve a more general solution.

Related Pages

Overview

Administrivia

Upcoming Work

Cool Things Coming to Campus

Academic

Peer Support

Miscellaneous

Analyzing Binary Search

Analyzing the Recursive Version

;;; Procedure:
;;;   binary-search
;;; Parameters:
;;;   vec, a vector to search
;;;   get-key, a procedure of one parameter that, given a data item,
;;;     returns the key of a data item
;;;   may-precede?, a binary predicate that tells us whether or not
;;;     one key may precede another
;;;   key, a key we're looking for
;;; Purpose:
;;;   Search vec for a value whose key matches key.
;;; Produces:
;;;   match, a number.
;;; Preconditions:
;;;   The vector is "sorted".  That is,
;;;     (may-precede? (get-key (vector-ref vec i))
;;;                   (get-key (vector-ref vec (+ i 1))))
;;;     holds for all reasonable i.
;;;   The get-key procedure can be applied to all values in the vector.
;;;   The may-precede? procedure can be applied to all pairs of keys
;;;     in the vector (and to the supplied key).
;;;   The may-precede? procedure is transitive.  That is, if
;;;     (may-precede? a b) and (may-precede? b c) then it must
;;;     be that (may-precede? a c).
;;;   If two values are equal, then each may precede the other.
;;;   Similarly, if two values may each precede the other, then
;;;     the two values are equal.
;;; Postconditions:
;;;   If vector contains no element whose key matches key, match is -1.
;;;   If vec contains an element whose key equals key, match is the
;;;     index of one such value.  That is, key is 
;;;       (get-key (vector-ref vec match))
(define binary-search
  (lambda (vec get-key may-precede? key)
    ; Search a portion of the vector from lower-bound to upper-bound
    (let search-portion ([lower-bound 0]
                         [upper-bound (- (vector-length vec) 1)])
      ; If the portion is empty
      (if (> lower-bound upper-bound)
          ; Indicate the value cannot be found
          -1
          ; Otherwise, identify the middle point, the element at that 
          ; point and the key of that element.
          (let* ([midpoint (quotient (+ lower-bound upper-bound) 2)]
                 [middle-element (vector-ref vec midpoint)]
                 [middle-key (get-key middle-element)]
                 [left? (may-precede? key middle-key)]
                 [right? (may-precede? middle-key key)])
            (cond
              ; If the middle key equals the value, we use the middle value.
              [(and left? right?)
               midpoint]
              ; If the middle key is too large, look in the left half
              ; of the region.
              [left?
               (search-portion lower-bound (- midpoint 1))]
              ; Otherwise, the middle key must be too small, so look 
              ; in the right half of the region.
              [else
               (search-portion (+ midpoint 1) upper-bound)]))))))

Analyzing this procedure (or any recursive procedure)

Iterative:

while (lb <= ub)
  mid = average(lb, ub)
  if (a[mid] == val)
    return mid;
  else if (a[mid] < val)
    lb = mid+1;
  else
    ub = mid-1;

Process

Analysis

Testing Binary Search

Lab