練習に「常に子よりも親が大きい(小さい)値の二分木をヒープという」を Gauche で書いてみた。
(use gauche.collection) (use gauche.uvector) (use srfi-43) ;;vector-swap! ;; 親の位置 (define (parent n) (quotient (- n 1) 2)) (define (vct-swap v x y) (begin (vector-swap! v x y) v)) (define (vect-if-swap vct x y) (if (>= (vector-length vct) 2) (if (< (vector-ref vct x)(vector-ref vct y)) vct (vct-swap vct x y)) vct)) ;; 親より値が大きければ値を交換。 (define (change vect pos) (if (> pos 0) (let* ((new-vect (vect-if-swap vect pos (parent pos)))) (change new-vect (parent pos))) vect)) ;; ヒープに値を追加。 (define (push-heap elem vect) (change (vector-append vect (vector elem)) (- (vector-length vect) 1))) ;; 二分木をS式で表示 (define (show_tree vect length n) (string-append "(" (number->string (vector-ref vect n)) " " (show_leaf vect length (+ (* n 2) 1) ) " " (show_leaf vect length (* 2 (+ n 1))) ")" )) (define (show_leaf vect length pos) (if (<= pos length) (show_tree vect length pos) "-")) (define vect '#()) (define v-dat '#(10 1 2 66 3 4 102 33 78 9 52)) (print (show_tree (fold push-heap vect v-dat) (- (vector-length v-dat) 1) 0)) ;;=> (102 (78 (33 (1 - -) (10 - -)) (9 (3 - -) (52 - -))) (66 (2 - -) (4 - -)))