sicp每日一题[2.65]
Exercise 2.65
Use the results of Exercise 2.63 and Exercise 2.64 to give (n) implementations of union-set and intersection-set for sets implemented as (balanced) binary trees.
这道题难度还是挺大的,一开始我不知道怎么直接对2颗树求交集和并集,而且要在 O(n) 的时间复杂度内。上网看了一下别人的答案,发现他们都是先用 2.63 的 tree->list-2 把树转为列表,然后再求交集并集,最后再用 2.64 的 list->tree 把结果转成树结构。
这样我就明白怎么做了,尤其是求并集可以直接参考 2.62 的答案,但是稍作修改,让它能去除重复元素,求交集虽然没有现成的,但是参考并集的方法也不难。
(define (union-tree tree1 tree2)
(define (union-set set1 set2)
(cond ((null? set2) set1)
((null? set1) set2)
(else (let ((s1 (car set1))
(s2 (car set2)))
(cond ((= s1 s2) (cons s1 (union-set (cdr set1) (cdr set2))))
((< s1 s2) (cons s1 (union-set (cdr set1) set2)))
(else (cons s2 (union-set set1 (cdr set2)))))))))
(list->tree (union-set (tree->list-2 tree1) (tree->list-2 tree2))))
(define (intersection-tree tree1 tree2)
(define (intersection-set set1 set2)
(if (or (null? set1) (null? set2))
'()
(let ((s1 (car set1))
(s2 (car set2)))
(cond ((= s1 s2) (cons s1 (intersection-set (cdr set1) (cdr set2))))
((< s1 s2) (intersection-set (cdr set1) set2))
(else (intersection-set set1 (cdr set2)))))))
(list->tree (intersection-set (tree->list-2 tree1) (tree->list-2 tree2))))
(define tree1 (list->tree (list 1 3 5 7 9 11)))
(define tree2 (list->tree (list 2 4 6 7 8 9 10)))
(intersection-tree tree1 tree2)
(union-tree tree1 tree2)
; 结果如下
'(7 () (9 () ()))
'(6 (3 (1 () (2 () ())) (4 () (5 () ()))) (9 (7 () (8 () ())) (10 () (11 () ()))))