SICP 問題 2.65(二進木の和集合、積集合を求める手続を定義する)

問題

問題 2.63 と問題 2.64 の結果を使い、(釣り合った)二進木として実装されている集合の union-set と intersection-set を Θ(n) で実装せよ。

解答

2つの集合(二進木)を、一度順序付けられたリストに変換して、その状態で和集合あるいは積集合を求め、その結果を改めて二進木にすればいいんじゃね?
どのプロセスも Θ(n) のオーダーだし。

;和集合
(define (union-set tree1 tree2)
  ;順序付けられたリストの和集合を求める手続。(SICP 問題 2.62)
  (define (union-set-for-ordered-list set1 set2)
    (cond ((null? set1)
	   set2)
	  ((null? set2)
	   set1)
	  (else
	   (let ((x1 (car set1))
		 (x2 (car set2)))
	     (cond ((= x1 x2)
		    (cons x1 (union-set-for-ordered-list (cdr set1) (cdr set2))))
		   ((< x1 x2)
		    (cons x1 (union-set-for-ordered-list (cdr set1) set2)))
		   (else ;(< x2 x1)
		    (cons x2 (union-set-for-ordered-list set1 (cdr set2)))))))))
  ;メイン処理
  (let ((l1 (tree->list-2 tree1))
	(l2 (tree->list-2 tree2)))
    (list->tree (union-set-for-ordered-list l1 l2))))

;積集合
(define (intersection-set tree1 tree2)
  ;順序付けられたリストの積集合を求める手続。
  ;(SICP § 2.3.3 集合の表現 その2 [順序づけられたリストとしての集合])
  (define (intersection-set-for-ordered-list set1 set2)
    (if (or (null? set1) (null? set2))
	'()
	(let ((x1 (car set1))
	      (x2 (car set2)))
	  (cond ((= x1 x2)
		 (cons x1 (intersection-set-for-ordered-list (cdr set1) (cdr set2))))
		((< x1 x2)
		 (intersection-set-for-ordered-list (cdr set1) set2))
		((< x2 x1)
		 (intersection-set-for-ordered-list set1 (cdr set2)))))))
  ;メイン処理
  (let ((l1 (tree->list-2 tree1))
	(l2 (tree->list-2 tree2)))
    (list->tree (intersection-set-for-ordered-list l1 l2))))

データ作るの大変だから実験しないけど・・・あってるよな?