Title: Vectors, binary search, and sorting
1Vectors, binary search, and sorting
2We know about lists
O(n) time to get the n-th item. Consecutive cons
cell are not necessarily consecutive in memory
3Alternatively, use indirect addressing
Put items consecutively in memory Knowing the
base we can calculate the address of the n-th
item ! so we can access the n-th item in O(1)
time -- random access What did we loose ? Cannot
easily add elements in the middle
4Indirect addressing in scheme -- via vectors
(define v (vector 3 '(2 3 b (4 5)) 'anna))
gt (3 (2 3 b (4 5)) anna)
v
(vector-length v)
gt 3
(car (vector-ref v 1))
gt 2
(vector-set! v 2 'foo)
gt (3 (2 3 b (4 5)) foo)
v
(define vv (make-vector 4 '()))
gt (() () () ())
vv
(vector-set! vv 2 (vector-ref v 2))
gt (() () foo ())
vv
(define ll (list vv v))
gt t
(vector? (car ll))
5Indirect addressing in scheme -- via vectors
(vector ... ) create a vector
from the 0 or more elements (make-vector k)
create a vector of length k (make-vector k
init) same, but each element is initialized
to init (vector-length vec) returns the
length of the vector vec (vector-ref vec k)
returns the element of vec with index k
k should be
between 0 and length-1 (vector-set! vec k elt)
stores elt in the element k of the
vector vec. k should be
between 0 and length-1 (vector? obj)
returns true if obj is a vector, false otherwise
6Binary search
- The algorithm needs random access
- The input vector must be sorted
- Compare x to the middle element of the vector
- If x is smaller then x must be in the first
half of the vector - If x is larger then x must be in the second
half of the vector - If x is equal, we found it
7Binary search (Cont.)
(define (bin-search vec x) (define (search left
right) (if (gt left right) nil
(let ((mid (average left right))
(mid-item (vector-ref vec mid))) (cond
(( x mid-item) mid) ((lt x
mid-item) (search left (- mid 1)))
(else (search ( mid 1) right))))))
(search 0 (- (vector-length vec) 1))) (define
(average x y) (round (/ ( x y) 2)))
8Binary search (Cont.)
- With one comparison, reduce search space to
half its size - Run time is ?(log n)
9Sorting
- Collection of data elements, which may be
compound - Each data element has a key, from ordered
domain. (In our example there will be just keys). - We would like to order the elements according
to the keys, in increasing order
10Bubble sort
- The algorithm compares neighbors, and exchanges
them when they are out of order - Go through elements from last to first,
performing this on each pair of neighbors, the
smallest element will reach its correct position
as first. - Make an additional pass, reaching the second
element only, and so on, until all elements are
in place
11Bubble sort
12Implementation of Bubble sort
(define (bubble-sort vec) (define n
(vector-length vec)) (define (iter i)
(define (bubble j) (if (gt j i)
(let ((prev (vector-ref vec (- j 1)))
(cur (vector-ref vec j))) (cond
((gt prev cur) (vector-set! vec
(- j 1) cur) (vector-set! vec
j prev))) (bubble (- j 1)))))
(cond ((lt i n) (bubble (- n 1))
(iter ( i 1))))) (iter 1))
13Bubble sort
- Number of comparisons is
- (n-1) (n-2) . . . . 1 n(n-1)/2
- Number of exchanges worst case, same as number
of comparisons best case 0. - In any case, the running time is ?(n2)
14Quicksort
- The algorithm chooses some element, called
pivot. - Splits the elements into three groups smaller
equal, and larger than the pivot. - Recursively sort the smaller and the larger
groups independently
15Quicksort (Cont.)
(define (quicksort l) (if (null? l) nil
(let ((pivot (car l))) (let ((low
(filter (lambda (x) (lt x pivot)) l))
(high (filter (lambda (x) (gt x pivot)) l))
(same (filter (lambda (x) ( x pivot))
l))) (append (append
(quicksort low) same) (quicksort
high))))))
16Quicksort -- brief analysis
T(n) cn T(m) T(n-m-1) where m is the number
of elements smaller than the pivot (for
simplicity assume the keys are all different).
17Quicksort -- brief analysis
T(n) ? cn c(n-1) c(n-2) c
cn(n1)/2 so T(n) O(n2)
Worst case is when m0 (or mn-1), giving T(n)
cn c(n-1) c(n-2) c cn(n1)/2 so
T(n) ?(n2)
Best case, when the algorithm partitions the
elements into two equal size groups at each stage.
18Other sorting algorithms
- Mergesort -- in homework
- Heapsort -- hopefully in the course about
data structures
19The metacircular evaluator
20The metacircular evaluator
- Parts of an interpreter
- Start growing the evaluator slowly
- Arithmetic calculator
- Add names
- Conditionals and if
- Store procedures in the environment
- Environment as explicit parameter
- Defining new procedures
21Why do we need an interpreter?
- Abstractions let us bury details and focus on use
of modules to solve large systems - Need to unwind abstractions at execution time to
deduce meaning - Have seen such a process Environment Model
- Now want to describe that process as a procedure
22Stages of an interpreter
input to each stage
Lexical analyzer
"(average 4 ( 5 5))"
Parser
Printer
7
"7"
23Role of each part of the interpreter
- Lexical analyzer
- break up input string into "words" called tokens
- Parser
- convert linear sequence of tokens to a tree
- like diagramming sentences in elementary school
- also convert self-evaluating tokens to their
internal values - f is converted to the internal false value
- Evaluator
- follow language rules to convert parse tree to a
value - read and modify the environment as needed
- Printer
- convert value to human-readable output string
24Our goal of the next few lectures
- Implement an interpreter for a programming
language - Only write evaluator and environment
- use scheme's reader for lexical analysis and
parsing - use scheme's printer for output
- to do this, our language must look like scheme
- Start with a simple calculator for arithmetic
- Progressively add scheme features until we have
the metacircular evaluator as in the book
251. Arithmetic calculator
- Want to evaluate arithmetic expressions of two
arguments, like - ( 24 ( 5 6))
26 (define (tag-check e sym) (and (pair? e) (eq?
(car e) sym))) (define (sum? e) (tag-check e
)) (define (eval exp) (cond ((number?
exp) exp) ((sum? exp) (eval-sum exp))
(else (error "unknown expression "
exp)))) (define (eval-sum exp) ( (eval
(cadr exp)) (eval (caddr exp)))) (eval '( 24
( 5 6)))
27We are just walking through a tree
sum? checks the tag
28We are just walking through a tree
( (eval 5) (eval 6))
291. Things to observe
- cond determines the expression type
- no work to do on numbers
- scheme's reader has already done the work
- it converts a sequence of characters like "24" to
an internal binary representation of the number
24 - eval-sum recursively calls eval on both argument
expressions
302. Names
- Extend the calculator to store intermediate
results as named values - (define x ( 4 5)) store result as x
- ( x 2) use that result
- Store bindings between names and values in a
table
312. Names (define (define? exp) (tag-check exp
'define)) (define (eval exp) (cond
((number? exp) exp) ((symbol? exp) (lookup
exp)) ((sum? exp) (eval-sum exp))
((define? exp) (eval-define exp)) (else
(error "unknown expression " exp)))) (define
environment (make-frame () ())) (define
(lookup name) (lookup-variable-value name
environment)) (define (eval-define exp) (let
((name (cadr exp))
(defined-to-be (eval (caddr exp))))
(add-binding-to-frame! name defined-to-be
environment) undefined))
32(define (make-frame variables values) (cons
variables values)) (define (lookup-variable-value
var frame) (define (scan vars vals) (cond
((null? vars) (error "Unbound variable" var))
((eq? var (car vars)) (car vals)) (else
(scan (cdr vars) (cdr vals))))) (let ((vars
(car frame)) (vals (cdr frame))) (scan vars
vals))) (define (add-binding-to-frame! var val
frame) (set-car! frame (cons var (car frame)))
(set-cdr! frame (cons val (cdr frame))))
33The environment is a single frame
frame
5
x
y
4
list of values
list ofvariables