CSC 151.01, Class 35: Binary search
Overview
- Preliminaries
- Notes and news
- Upcoming work
- Extra credit
- Questions
- Divide and conquer
- Destructive binary search (a demonstration)
- Binary search in Scheme
- Lab
- Debrief
News / Etc.
- Quiz 12 returned.
- I expect that the next set of grades you get from me will be after Thanksgiving.
Upcoming Work
- Writeup for class 35 due Wednesday at 10:30 p.m.
- Exercise 3
- To: csc151-01-grader@grinnell.edu
- Subject: CSC 151.01 Writeup 35 (YOUR NAMES)
- Project proposals due TONIGHT.
- Projects due next Tuesday.
- No reading for Wednesday.
- No quiz this week.
Extra credit (Academic/Artistic)
- Tuesday community hour panel on guns.
- CS table tomorrow: Uber and “the gig economy”.
Extra credit (Peer)
Extra credit (Misc)
Other good things
- Harp recital Tuesday night.
Questions
Divide and conquer
Traditionally, we search lists with linear search (as in association list). We look at element 0. If it matches, we’re done. We look at element 1. If it matches, we’re done. We look at element 2. If it matches, we’re done. We look at element 3. If it matches, we’re done. And so on and so forth.
If a list has n elements, we potentially look at all of them. In the worst case (it’s not there), we do look at all of them.
Can we do better?
If we can arrange the elements in order from smallest to largest, in a vector, we can look in the middle. (Or we run out of elements.)
- The middle element can match. We’re done.
- The middle element can be too big. We look in the stuff before it.
- The middle element can be too small. We look in the stuff after it.
Destructive binary search (a demonstration)
How many names did I have to look at?
1600 -> 800 -> 400 -> 200 -> 100 -> 50 -> 25 -> 12 -> 6 -> 3 -> 1 -> Done
It tooks us about eleven recursive calls to find a person out of 1600.
If we had 4,000,000 (Manhattan, Iowa). About 22 steps.
Binary search is a great algorithm, but has restrictions that
- The data are stored in a vector. And use the vector cleverly.
- The data must be arranged from smallest to largest.
Binary search in Scheme
Explain each of the four parameters to binary search.
(define binary-search
(lambda (vec get-key may-precede? key)
vecis a vector.keyis a value, which represents the thing we want.get-keyis a procedure which extracts the key.- What is “the key”? The important part of each entry. Like in assoc, where the first element of each list is the key.
- The generalized “tell us what’s important”
may-precede?tells us what can come before something else.- If we organize the vector using strings, it’s
string-ci<=?orstring=? - If the keys are integers, it’s <=.
- If we organize the vector using strings, it’s
In the following vector of people with sidekicks arranged by protagonist, the car is the key
(define sidekicks
(vector
("Batman" "Robin")
("Halle" "Marli")
("Scooby" "Shaggy")
("Superman" "Krypto")
("Yogi" "Booboo")
))
To search that vector for Secret Squirrel’s sidekick, I’d use
(binary-search sidekicks car string-ci<=? "Secret Squirrel")
(define sidekicks-by-sidekick
(vector
("Yogi" "Booboo")
("Halle" "Marli")
("Superman" "Krypto")
("Batman" "Robin")
("Scooby" "Shaggy")
))
To find out Robin’s protagonist, I might use something like
(binary-serach sidekicks-by-sidekick cadr string-ci<=? "Robin")
We can arrange the elements however we want. I’ll generally use lists for each element, but you could also use a vector or a tree or ….
What does binary search return?
It returns the index of the matching element. It returns -1 if it doesn’t match.
How do we apply the “divide and conquer” technique without building new vectors (which is computationally expensive)?
Instead of literally throwing away half the vector, we keep track of the start and end of the portion still of interest. You can find the midpoint and refine your knowledge of the start and end of that portion.
Lab
Observation: Since the way we decide that it’s a match is to check
whether the desired key may precede the middle key AND the middle key
may precede the desired key, we need to use <= rather than < as
may-precede?.
Observation: If the same key appears multiple times, it is difficult to predict which instance is chosen. (It is also not consistent.) That is a consequence of how binary search works; it’s whichever one appears in the middle of the range of interest.
For exercise 5, I mean caddr, not (r-s list-ref 5).
Writeup: Exercise 3
Debrief
For exercise 4: What happens right before the element is not found?
- Option 1:
lower-bound=upper-boundand the middle element is too large. We now haveupper-bound=lower-bound-1. - Option 2:
lower-bound=upper-boundand the middle element is too small. We now havelower-bound=upper-bound+1. - Option 3:
lower-bound=upper-bound-1 (which means that the middle element is atlower-bound) and the middle element is too large. We now haveupper-bound=lower-bound-1. - Option 4:
lower-bound=upper-bound-1 (which means that the middle element is atlower-bound) and the middle element is too small. We now havelower-bound=upper-boundand we’re in one of the three other options.