赤黒木 (8)
insertion case 4a. および insertion case 4b. の確認。
insertion case 4a
ええと初期状態が以下で
;; R:-4 ;; B:-3 ;; R:-2 ;; R:-1 ;; R:-0.7 ;; B:-0.5 ;; B:0 ;; B:2.5 ;; R:4
ここに -0.6 な要素を追加するようです。最初はこうなるんかな。
;; R:-4 ;; B:-3 ;; R:-2 ;; R:-1 ;; R:-0.7 ;; R:-0.6 ;; B:-0.5 ;; B:0 ;; B:2.5 ;; R:4
これは単に left-rotate! から right-rotate! のパターンなのかな。確認します。上記の状態で put-fixup! が呼び出されます。
(define (put-fixup! tree z) (let loop ((z z)) (when (red? (parent z)) (let* ((b (eq? (parent z) (left (parent (parent z))))) (y (right* (parent (parent z)) b)))
- z (key が -0.6) の親は無論赤 (key が -0.7)
- z の親はそのまた親の左側の要素なので b は真
- z の親の対面は nil なので (key が -0.5 の要素の右側要素は nil) y も nil
というあたりを前提にするとまず
(if (red? y)
は偽なので以下なブロックが評価されます。
(let1 z (if (eq? z (right* (parent z) b)) (begin0 (parent z) (left-rotate! tree (parent z) b)) z) (paint-black! (parent z)) (paint-red! (parent (parent z))) (right-rotate! tree (parent (parent z)) b))))))
ええと、b は真で z の親に対して z は右側になりますね。ので if の then ブロックが評価されることになります。で、基本的には
- x (key が -0.7) の親の左要素は y(key が -0.6) の要素に
- y (key が -0.6) の左が x (key が -0.7) に
- x (key が -0.7) の親が y (key が -0.6) に
ということで
;; R:-0.7 ;; R:-0.6 ;; B:-0.5
ということになるんですかね。これはこのまんま
;; R:-0.7 => -0.7 ;; B:-0.6 => -0.6 ;; R:-0.5 => -0.5
になって終わりなカンジですね。insertion case 4b も同様なカンジ。
とゆーことで
例のソレな分岐は通過しない、ということなのかな。Shiro さんの treemap の実装も別途精査できればと思ってます。明日以降で削除なナニを精査の方向にて。