Binary Search
Summary:
In this laboratory, we explore different issues related to searching.
Exercise 0: Preparation
a. Make a copy of binary-search-lab.scm, the code for this lab.
b. Read through the definition of binary-search,
and make sure that you understand the role of get-key
in that definition.
Exercises
Exercise 1: Observing Binary Search
a. Verify that binary search can correctly find the entry for
"Heather"
in objects-by-name. That is, write an expression to find
"Heather".
> (binary-search objects-by-name ___ ___ "Heather")
b. Verify that binary search can correctly find the entry for
an object of your choice in objects-by-name.
c. Verify that binary search can correctly find the first entry
in objects-by-name. You will need to supply the
name associated with that entry.
d. Verify that binary search can correctly find the last entry
in objects-by-name. You will need to supply the
name associated with that entry.
e. Verify that binary search terminates and returns -1 for something
that would fall in the middle of the vector and is not there. That
is, pick a name that starts with M or N and that does not appear in
the vector.
f. Verify that binary search terminates and returns -1 for something
that comes before the first entry in
objects-by-name. You will need to pick a name that
alphabetically precedes "Amy".
g. Verify that binary search terminates and returns -1 for something that
comes after the last entry. You will need to pick a name that
alphabetically follows "Zed".
Exercise 2: Counting Recursive Calls
It is often useful when exploring a recursive algorithm to observe the
steps the algorithm performs. In Scheme, we can sometimes observe steps
in recursive calls by inserting code to display the parameters of the
procedure at each recursive call.
a. Add calls to display
and newline to the definition of
binary-search, so that it prints out the values
of lower-bound and upper-bound
each time the kernel procedure is called.
b. Redo steps a-g of Exercise 1 and report on the number of steps each
search took.
c. Optional: You might also use
define$ and analyze
to do the counting for you.
Exercise 3: Duplicate Keys
a. What do you expect binary search do if there are entries with
duplicate keys?
b. Add two more entries with a key of "Otto" and two more
entries with a key of "Amy". These new entries should be
slightly different, so that you can tell them apart.
c. Which of the three do you expect binary search to return if you
search for "Otto"?
d. Check your answer experimentally.
e. Which of the three do you expect binary search to return if you
search for "Amy"?
f. Check your answer experimentally.
g. What does your experience in this exercise suggest about what
binary search will do with multiple keys?
Exercise 4: Searching by Width
As you may have observed, objects-by-width contains
the same twenty-six objects as in object-by-name, but
with the objects organized by their width, rather than by name.
a. Write an expression to find an object with a width of 45.
> (binary-search objects-by-width ___ ___ 45)
b. Write an expression to find an object whose width is 40.
c. Write an expression to find an object whose width is 35.
d. What, if anything, can you say about what binary search does
when searching for a key that appears more than once in the
vector?
Exercise 5: Binary Search, Revisited
It is sometimes useful to learn not just that something is not
in the vector, but where it would fall if it were in the vector.
Write documentation and code for new-binary-search
that mostly behaves like binary-search, except
that it returns a half value
if the value being
searched for belongs between two neighboring values. For example,
if the key being searched for is larger than the key at position 5 and
smaller than the key at position 6, you should return 5.5. Similarly,
if the key being searched for is smaller than the key at position 0,
you should return -1/2. If the key being searched for is bigger than
the largest key, return (- (vector-length vec) 0.5).
For example,
> (new-binary-search objects-by-name car string<=? "Andy")
0.5
> (new-binary-search objects-by-name car string<=? "Greg")
7
> (new-binary-search objects-by-name car string<=? "Heather")
8
> (new-binary-search objects-by-name car string<=? "Hanna")
7.5
> (new-binary-search objects-by-width (r-s list-ref 5) <= 1)
-0.5
> (new-binary-search objects-by-width (r-s list-ref 5) <= 6)
3.5
> (new-binary-search objects-by-width (r-s list-ref 5) <= 60)
25.5
You should use the code for binary-search as your
starting point.
Exercise 6: Searching Alternate Vectors
Here are commands to search objects-by-name for
"Paula" and objects-by-width for something
with width 45.
> (binary-search objects-by-name car string<=? "Paula")
> (binary-search objects-by-width (r-s list-ref 5) <= 45)
a. What do you expect to have happen if we swap the vectors in these
commands, as in the following?
> (binary-search objects-by-width car string<=? "Paula")
> (binary-search objects-by-name (r-s list-ref 5) <= 45)
b. Check your answer experimentally.
c. Try searching objects-by-width for the names
"Otto", "Erin", "Fred", "Charlotte", "Janet", and "Xerxes".
d. What do the previous steps of this experiment tell you about binary search?