;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; U. C. Berkeley ;; ;; EECS Computer Science Division ;; ;; CS3 Lecture 20 Answers ;; ;; (Trees) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; CONSTRUCTORS AND SELECTORS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Essential (define (make-node datum children) (cons datum children)) (define (datum node) (car node)) (define (children node) (cdr node)) ;; Time-savers (built using above) (define (leaf? node) (null? (children node))) (define (make-leaf datum) (make-node datum '())) (define (make-leaves datum-list) (map make-leaf datum-list)) ;;;;;;;;;;;;; ;; STATE TREE ;;;;;;;;;;;;; (make-node 'ca (list 'sf 'berkeley 'la)) ;; ==> (ca sf berkeley la) ;; ==> Error: This is not a tree! (define *our-state* (make-node 'ca (make-leaves '(sf berkeley la)))) ;; Now let's try to get "berkeley" (first (first (bf (bf *our-state*)))) ;; ==> berkeley ;; ==> Data Abstraction Violation! DAV! (caaddr *our-state*) ;; ==> berkeley ;; ==> DAV! (datum (list-ref (children *our-state*) 1)) ;; ==> berkeley ;; ==> Correct use of abstraction! ;;;;;;;;;;;;;; ;; NUMBER TREE ;;;;;;;;;;;;;; (define *number-tree* (make-node 6 (list (make-node 2 (make-leaves '(3 8))) (make-node 4 (list (make-leaf 16) (make-node 1 (make-leaves '(10 4)))))))) *number-tree* ;; ==> (6 (2 (3) (8)) (4 (16) (1 (10) (4)))) ;;;;;;;;;;;;; ;; TREE-EVERY ;;;;;;;;;;;;; ;; Recall my-every (define (my-every fn s) (if (empty? s) '() (se (fn (first s)) (my-every fn (bf s))))) (my-every square '(1 2 3 4)) ;; ==> (1 4 9 16) ;; Now, tree-every (define (tree-every fn node) (make-node (fn (datum node)) (tree-every-forest fn (children node)))) (define (tree-every-forest fn forest) (if (null? forest) '() (cons (tree-every fn (car forest)) (tree-every-forest fn (cdr forest))))) (define (square x) (* x x)) (tree-every square *number-tree*) ;; ==> (36 (4 (9) (64)) (16 (256) (1 (100) (16)))) (define (tree-every-using-map fn node) (make-node (fn (datum node)) (map (lambda (child) (tree-every-using-map fn child)) (children node) ))) (tree-every-using-map square *number-tree*) ;; ==> (36 (4 (9) (64)) (16 (256) (1 (100) (16)))) ;;;;;;;;;;; ;; TREE-SUM ;;;;;;;;;;; (define (tree-sum node) (+ (datum node) (reduce + (map tree-sum (children node))))) (tree-sum *number-tree*) ;; ==> 54 ;;;;;;;;;;;;;;;;;; ;; SUBSTITUTE-TREE ;;;;;;;;;;;;;;;;;; (define (substitute-tree tree old new) (tree-every (lambda (the-datum) (if (equal? the-datum old) new the-datum)) tree)) *number-tree* ;; ==> (6 (2 (3) (8)) ( 4 (16) (1 (10) ( 4)))) (substitute-tree *number-tree* 4 99) ;; ==> (6 (2 (3) (8)) (99 (16) (1 (10) (99)))) ;;;;;;;;;;;;;;;;;;;;; ;; COUNT-ELTS-IN-TREE ;;;;;;;;;;;;;;;;;;;;; (define (count-elts-in-tree tree elt) (+ (if (equal? (datum tree) elt) 1 0) (count-elts-in-forest (children tree) elt))) (define (count-elts-in-forest forest elt) (if (null? forest) 0 (+ (count-elts-in-tree (car forest) elt) (count-elts-in-forest (cdr forest) elt)))) (count-elts-in-tree *number-tree* 4) ;; ==> 2 ;;;;;;;;;;;;;;;;;;;;;;;; ;; SMALLEST-TREE-ELEMENT ;;;;;;;;;;;;;;;;;;;;;;;; (define (smallest-tree-element tree) (if (leaf? tree) (datum tree) (min (datum tree) (reduce min (map smallest-tree-element (children tree)))))) (smallest-tree-element *number-tree*) ;; ==> 1 ;;;;;;;;;;;;;;; ;; UPDATE-NODES ;;;;;;;;;;;;;;; (define (update-nodes tree) (if (leaf? tree) tree (let ((new-forest (map update-nodes (children tree)))) (make-node (reduce + (map datum new-forest)) new-forest)))) *number-tree* ;; ==> ( 6 ( 2 (3) (8)) ( 4 (16) ( 1 (10) (4)))) (update-nodes *number-tree*) ;; ==> (41 (11 (3) (8)) (30 (16) (14 (10) (4))))