3 (defun update-balance-factors (tree direction-stack)
4 (loop with y = (root tree)
7 with reversed-stack = (nreverse direction-stack)
8 for x on reversed-stack
9 and xp = nil then (car x)
10 do (let ((node (caar x)))
11 (when (not (zerop (balance-info node)))
12 (setf y node parent xp tail x)))
15 ;; If TAIL is NIL, then we have an entire path of nodes with
16 ;; zero balance factors and the whole path needs to be
18 (dolist (p (if (null tail)
23 (if (eq (cdr p) 'left)
24 (decf (balance-info node))
25 (incf (balance-info node))))))))
27 (defun avl-rebalance/insert (tree direction-stack)
29 (multiple-value-bind (y parent-entry)
30 (update-balance-factors tree direction-stack)
31 (case (balance-info y)
34 (ecase (balance-info x)
36 (setf w (rotate-right y)
37 (balance-info x) +avl-equal+
38 (balance-info y) +avl-equal+))
40 (setf (left y) (rotate-left x)
42 (case (balance-info w)
44 (setf (balance-info x) 0
45 (balance-info y) +avl-leans-right+))
47 (setf (balance-info x) 0
50 (setf (balance-info x) +avl-leans-left+
52 (setf (balance-info w) +avl-equal+)))
53 (set-root-or-entry-child tree parent-entry w)))
55 (let ((x (right y)) w)
56 (ecase (balance-info x)
58 (setf w (rotate-left y)
59 (balance-info x) +avl-equal+
60 (balance-info y) +avl-equal+))
62 (setf (right y) (rotate-right x)
64 (case (balance-info w)
66 (setf (balance-info x) 0
67 (balance-info y) +avl-leans-left+))
69 (setf (balance-info x) 0
72 (setf (balance-info x) +avl-leans-right+
74 (setf (balance-info w) +avl-equal+)))
75 (set-root-or-entry-child tree parent-entry w)))))))
77 (defun avl-rebalance/delete (tree node replacement stack)
79 initially (unless (and (null (right node))
80 (eq replacement (left node)))
81 (setf (balance-info replacement) (balance-info node)))
82 for (top . rest) on stack
83 do (let ((y (car top))
84 (direction (cdr top)))
85 (macrolet ((frob (dir opp r1 r2)
86 (flet ((ifleft (dir f1 f2)
91 (if (eq dir 'left) a (- a))))
93 (,(ifleft dir 'incf 'decf) (balance-info y))
94 (case (balance-info y)
95 (,(leftinfo dir +avl-leans-right+)
97 (,(leftinfo dir +avl-falls-right+)
99 (case (balance-info x)
100 (,(leftinfo dir +avl-leans-left+)
102 (setf (,opp y) (,r1 x))
105 (case (balance-info w)
106 (,(leftinfo dir +avl-leans-right+)
107 (setf (balance-info x) +avl-equal+
108 (balance-info y) ,(leftinfo dir +avl-leans-left+)))
109 (,(leftinfo dir +avl-equal+)
110 (setf (balance-info x) +avl-equal+
111 (balance-info y) +avl-equal+))
112 (,(leftinfo dir +avl-leans-left+)
113 (setf (balance-info x) ,(leftinfo dir +avl-leans-right+)
114 (balance-info y) +avl-equal+)))
115 (setf (balance-info w) 0)
116 (set-root-or-entry-child tree (first rest) w))))
119 (set-root-or-entry-child tree (first rest) r)
121 ((= (balance-info x) +avl-equal+)
122 (setf (balance-info x) ,(leftinfo dir +avl-leans-left+)
123 (balance-info y) ,(leftinfo dir +avl-leans-right+))
126 (setf (balance-info x) +avl-equal+
127 (balance-info y) +avl-equal+)))))))))))))
129 (left (frob left right rotate-right rotate-left))
130 (right (frob right left rotate-left rotate-right)))))))
132 (unless (assoc :avl *binary-tree-info*)
135 #'avl-rebalance/insert
136 #'avl-rebalance/delete)