Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #lang racket
- ;;;;;;;;;;
- ;; 2.59 ;;
- ;;;;;;;;;;
- ;; sets as unordered lists without duplicates
- (define (element-of-set? x st)
- (cond [(empty? st) #f]
- [(equal? x (first st)) #t]
- [else (element-of-set? x (rest st))]))
- (define (adjoin-set x st)
- (if (element-of-set? x st) st (cons x st)))
- (define (intersection-set st1 st2)
- (cond [(or (empty? st1) (empty? st2)) empty]
- [(element-of-set? (first st1) st2)
- (cons (first st1)
- (intersection-set (rest st1) st2))]
- [else (intersection-set (rest st1) st2)]))
- (define (union-set st1 st2)
- (cond [(empty? st1) st2]
- [(empty? st2) st1]
- [(element-of-set? (first st1) st2)
- (union-set (rest st1) st2)]
- [else (cons (first st1)
- (union-set (rest st1) st2))]))
- (define st1 '(0 4 2 1 3))
- (define st2 '(5 3 7 4 6))
- (element-of-set? 7 st1)
- ;; #f
- (element-of-set? 4 st1)
- ;; #t
- (intersection-set st1 st2)
- ;; '(4 3)
- (union-set st1 st2)
- ;; '(0 2 1 5 3 7 4 6)
- ;;;;;;;;;;
- ;; 2.60 ;;
- ;;;;;;;;;;
- ;; sets as unordered lists with duplicates allowed
- (define (new-adjoin-set x st) (cons x st))
- (define (new-union-set st1 st2) (append st1 st2))
- ;; Only adjoin-set and union-set would change. adjoin-set becomes constant time,
- ;; and union-set becomes O(n). element-of-set? is still O(n) and
- ;; intersection-set is still O(n ^ 2). However, this n is no longer the number of
- ;; elements in the set. n is now the number of elements in the list, which could
- ;; be arbitrarily larger. So allowing duplicates is only something you would do
- ;; if you needed to do many adjoin-sets and did not need the other operations to
- ;; run efficiently.
- ;;;;;;;;;;
- ;; 2.61 ;;
- ;;;;;;;;;;
- ;; sets as ordered lists
- (define (ordered-element-of-set? x st)
- (cond [(empty? st) #f]
- [(= x (first st)) #t]
- [(< x (first st)) #f]
- [else (ordered-element-of-set? x (rest st))]))
- (define (ordered-intersection-set st1 st2)
- (cond [(or (empty? st1) (empty? st2)) empty]
- [else
- (define x1 (first st1))
- (define x2 (first st2))
- (cond [(= x1 x2)
- (cons x1 (ordered-intersection-set (rest st1) (rest st2)))]
- [(< x1 x2) (ordered-intersection-set (rest st1) st2)]
- [else (ordered-intersection-set st1 (rest st2))])]))
- (define (ordered-adjoin-set x st)
- (cond [(empty? st) (list x)]
- [(= x (first st)) st]
- [(< x (first st)) (cons x st)]
- [else (cons (first st) (ordered-adjoin-set x (rest st)))]))
- ;; ordered-adjoin-set will terminate when we encounter an element of st that is
- ;; bigger than or equal to x. On average this will happen after examining half
- ;; the elements in st.
- ;;;;;;;;;;
- ;; 2.62 ;;
- ;;;;;;;;;;
- (define (ordered-union-set st1 st2)
- (cond [(empty? st1) st2]
- [(empty? st2) st1]
- [else
- (define x1 (first st1))
- (define x2 (first st2))
- (cond [(= x1 x2)
- (cons x1 (ordered-union-set (rest st1) (rest st2)))]
- [(< x1 x2)
- (cons x1 (ordered-union-set (rest st1) st2))]
- [else (cons x2 (ordered-union-set st1 (rest st2)))])]))
- (define st3 '(0 1 2 3 4))
- (define st4 '(3 4 5 6 7))
- (ordered-element-of-set? 7 st3)
- ;; #f
- (ordered-element-of-set? 4 st3)
- ;; #t
- (ordered-intersection-set st3 st4)
- ;; '(3 4)
- (ordered-union-set st3 st4)
- ;; '(0 1 2 3 4 5 6 7)
- ;;;;;;;;;;
- ;; 2.63 ;;
- ;;;;;;;;;;
- ;; sets as binary trees
- (define (entry tree) (first tree))
- (define (left-branch tree) (second tree))
- (define (right-branch tree) (third tree))
- (define (make-tree entry left right) (list entry left right))
- (define (tree-element-of-set? x st)
- (cond [(empty? st) #f]
- [(= x (entry st)) #t]
- [(< x (entry st))
- (tree-element-of-set? x (left-branch st))]
- [else (tree-element-of-set? x (right-branch st))]))
- (define (tree-adjoin-set x st)
- (cond [(empty? st) (make-tree x empty empty)]
- [(= x (entry st)) st]
- [(< x (entry st))
- (make-tree (entry st)
- (tree-adjoin-set x (left-branch st))
- (right-branch st))]
- [else (make-tree (entry st)
- (left-branch st)
- (tree-adjoin-set x (right-branch st)))]))
- ;; two ways to convert a bst into a list
- (define (tree->list1 tree)
- (if (empty? tree)
- empty
- (append (tree->list1 (left-branch tree))
- (cons (entry tree)
- (tree->list1 (right-branch tree))))))
- (define (tree->list2 tree)
- (define (copy-to-list tree result-list)
- (if (empty? tree)
- result-list
- (copy-to-list (left-branch tree)
- (cons (entry tree)
- (copy-to-list (right-branch tree)
- result-list)))))
- (copy-to-list tree empty))
- (define tree-2-16-1 (make-tree 7
- (make-tree 3
- (list 1 empty empty)
- (list 5 empty empty))
- (make-tree 9
- empty
- (list 11 empty empty))))
- (define tree-2-16-2 (make-tree 3
- (list 1 empty empty)
- (make-tree 7
- (list 5 empty empty)
- (make-tree 9
- empty
- (list 11 empty empty)))))
- (define tree-2-16-3 (make-tree 5
- (make-tree 3
- (list 1 empty empty)
- empty)
- (make-tree 9
- (list 7 empty empty)
- (list 11 empty empty))))
- (displayln tree-2-16-1)
- ;; (7 (3 (1 () ()) (5 () ())) (9 () (11 () ())))
- (tree->list1 tree-2-16-1)
- ;; '(1 3 5 7 9 11)
- (tree->list2 tree-2-16-1)
- ;; '(1 3 5 7 9 11)
- (displayln tree-2-16-2)
- ;; (3 (1 () ()) (7 (5 () ()) (9 () (11 () ()))))
- (tree->list1 tree-2-16-2)
- ;; '(1 3 5 7 9 11)
- (tree->list2 tree-2-16-2)
- ;; '(1 3 5 7 9 11)
- (displayln tree-2-16-3)
- ;; (5 (3 (1 () ()) ()) (9 (7 () ()) (11 () ())))
- (tree->list1 tree-2-16-3)
- ;; '(1 3 5 7 9 11)
- (tree->list2 tree-2-16-3)
- ;; '(1 3 5 7 9 11)
- ;; a. The two procedures do produce the same result for every tree. Both produce
- ;; a left traversal of the tree.
- ;; b. Both trees make two recursive calls on subproblems of about half-size, but
- ;; tree->list2 does constant work outside the recursion while tree->list1 does
- ;; linear work outside the recursion because of the call to append. So
- ;; tree->list2 should be O(n), and tree->list1 should be O(n log n).
- ;;;;;;;;;;
- ;; 2.64 ;;
- ;;;;;;;;;;
- (define (list->tree elements)
- (first (partial-tree elements (length elements))))
- (define (partial-tree elts n)
- (cond [(zero? n) (cons empty elts)]
- [else
- (define left-size (quotient (sub1 n) 2))
- (define left-result (partial-tree elts left-size))
- (define left-tree (first left-result))
- (define non-left-elts (rest left-result))
- (define right-size (- n (add1 left-size)))
- (define this-entry (first non-left-elts))
- (define right-result (partial-tree (rest non-left-elts) right-size))
- (define right-tree (first right-result))
- (define remaining-elts (rest right-result))
- (cons (make-tree this-entry left-tree right-tree)
- remaining-elts)]))
- ;; a. partial-tree takes an ordered list and a number, and returns a list
- ;; containing: a balanced binary tree consisting of the first number elements of
- ;; the ordered list, and the remaining unused elements. The procedure works by
- ;; splitting the requisite number of elements into a triple of smaller numbers, a
- ;; middle number, and bigger numbers, recursively sending off the smaller and
- ;; bigger numbers to be made into trees, then using those trees as branches to
- ;; create the top-level tree having the middle element as entry.
- (partial-tree '(1 2 3 4) 0)
- ;; '(() 1 2 3 4)
- (partial-tree '(1 2 3 4) 1)
- ;; '((1 () ()) 2 3 4)
- (partial-tree '(1 2 3 4) 2)
- ;; '((1 () (2 () ())) 3 4)
- (partial-tree '(1 2 3 4) 3)
- ;; '((2 (1 () ()) (3 () ())) 4)
- (partial-tree '(1 2 3 4) 4)
- ;; '((2 (1 () ()) (3 () (4 () ()))))
- (list->tree '(1 3 5 7 9 11))
- ;; '(5 (1 () (3 () ())) (9 (7 () ()) (11 () ())))
- ;; 5
- ;; / \
- ;; 1 9
- ;; / \ / \
- ;; 3 7 11
- ;; b. partial-tree does constant work outside the recursion and makes two
- ;; recursive calls, each on a subproblem of about half size. So the recursion
- ;; tree has n nodes and thus partial-tree runs in linear time.
- ;;;;;;;;;;
- ;; 2.65 ;;
- ;;;;;;;;;;
- ;; We can get linear time union-set and intersection-set for our tree
- ;; representation of sets by: taking a tree, converting it into an ordered list
- ;; in linear time using tree->list2, then using the linear time operations we have
- ;; for sets as ordered lists, then converting back into trees, again in linear
- ;; time, using list->tree.
- (define (tree-union-set t1 t2)
- (define l1 (tree->list2 t1))
- (define l2 (tree->list2 t2))
- (define list-result (ordered-union-set l1 l2))
- (list->tree list-result))
- (define (tree-intersection-set t1 t2)
- (define l1 (tree->list2 t1))
- (define l2 (tree->list2 t2))
- (define list-result (ordered-intersection-set l1 l2))
- (list->tree list-result))
- (define t1 (make-tree 3
- (list 1 empty empty)
- (make-tree 7
- (list 5 empty empty)
- (make-tree 9
- empty
- (list 11 empty empty)))))
- (tree->list2 t1)
- ;; '(1 3 5 7 9 11)
- (define t2 (make-tree 5
- (make-tree 2
- (list 1 empty empty)
- empty)
- (make-tree 8
- (list 7 empty empty)
- (list 11 empty empty))))
- (tree->list2 t2)
- ;; '(1 2 5 7 8 11)
- (tree-union-set t1 t2)
- ;; '(5 (2 (1 () ()) (3 () ())) (8 (7 () ()) (9 () (11 () ()))))
- (tree->list2 (tree-union-set t1 t2))
- ;; '(1 2 3 5 7 8 9 11)
- (tree-intersection-set t1 t2)
- ;; '(5 (1 () ()) (7 () (11 () ())))
- (tree->list2 (tree-intersection-set t1 t2))
- ;; '(1 5 7 11)
- ;;;;;;;;;;
- ;; 2.66 ;;
- ;;;;;;;;;;
- (define (tree-lookup given-key set-of-records)
- (cond [(empty? set-of-records) #f]
- [(= given-key (entry set-of-records))
- (entry set-of-records)]
- [(< given-key (entry set-of-records))
- (tree-lookup given-key (left-branch set-of-records))]
- [else (tree-lookup given-key (right-branch set-of-records))]))
- (displayln t1)
- ;; (3 (1 () ()) (7 (5 () ()) (9 () (11 () ()))))
- (tree-lookup 9 t1)
- ;; 9
- (tree-lookup 8 t1)
- ;; #f
Add Comment
Please, Sign In to add comment