rsr5スキームで表現された考え
私の最初の考えは、ノードが値とツリーを取り、関数が見つかったのと同じ場所でその値をそのツリーに挿入する関数である無限ツリーに関するものです。次に、リストに対してfold2のような再帰を実行し、関数ツリーのレベルオーダートランスバーサルを実行して、連続するリスト要素に連続する関数を適用し、バイナリツリーを蓄積します。(ただし、遅延評価でのみ機能します)
少し扱いにくそうだったので、 ('l 'r 'l) のような関数や、どこに挿入してインデックスを付けるかを伝えることができるデータのツリーに考えを修正しました。
(define (insert-new ls-and-rs tree)
(cond ((or (empty-tree?) (null? ls-and-rs))
(if (and (empty-tree?) (null? ls-and-rs))
(make-tree x emptyTree emptyTree)
(error "insert-new can only insert at emptyree")))
((sybol=? (car ls-and-rs) 'l)
(make-tree (node tree)
(insert-new (cdr ls-and-rs)
(left-tree tree))
(right-tree tree)))
((sybol=? (car ls-and-rs) 'r)
(make-tree (node tree)
(left-tree tree)
(insert-new (cdr ls-and-rs)
(right-tree tree))))
(else (error "insert-new expected 'l or 'r, recieved "
(car ls-and-rs))))))
次に、インデックス自体からそれを構築できることがわかりました。1 がツリーの先頭の場合のインデックス。それ以外の場合は、ノードの右分岐です。左枝さえあれば。その親のインデックスは、常に子のフロアを 2 で割ったものです。その知識から、単にインデックスを使用してインサーターまたはアクセサーを構築できます。
(define (branch-order i)
(let loop ((i i) (accum '()))
(cond ((i = 1) accum)
((odd? i) (loop (quotient i 2) (cons 'r accum)))
(else (loop (quotient i 2) (cons 'l accum))))))
そこからは単純な再帰です
(define (list->tree list)
(let loop ((list list) (i 1) (tree emptyTree))
(cond ((null? list) tree)
(else (loop (cdr list)
(+ i 1)
(insert-new (branch-order i) tree))))))
もちろん、最も簡単な方法は、最小深度のバイナリ ツリーを受け入れることができる場合です。深さツリーには、ノードとブランチに加えて、最小の深さがリストされます。次に、右のサブツリーの最小の深さが左のサブツリーよりも小さい場合を除き、挿入は左のサブツリーに挿入されます。
(define (list->d-tree list)
(fold-left (flip balanced-insert) emptyTree list))
(define (balanced-insert x d-tree)
(cond ((= 0 (d-d-tree d-tree))
(mk-d-tree x emptyTree emptyTree)
((= 1 (- (d-d-tree d-tree) (d-d-tree (l-d-tree d-tree))))
(mk-d-tree (n-d-tree d-tree)
(balanced-insert x (l-d-tree d-tree))
(r-d-tree d-dtree)))
(else
(mk-d-tree (n-d-tree d-tree)
(l-d-tree d-tree)
(balanced-insert x (r-d-tree d-dtree))))))
(define (mk-d-tree n l r)
(let ((d-l (d-d-tree l))
(d-r (d-d-tree r)))
(list n l r (+ 1 (min d-l d-r)))))
(define (n-d-tree d-tree)
(car d-tree))
(define (l-d-tree d-tree)
(cadr d-tree))
(define (r-d-tree d-tree)
(caddr d-tree))
(define (d-d-tree d-tree)
(if emptyTree? d-tree)
0
(cadddr d-tree)))
(define (emptyTree? tree)
(null? tree))
(define emptyTree '())
(define (flip f)
(lambda (a b)
(f b a)))
TLdr; 最小深度ツリーを使用し、左端の最小深度に挿入します。