Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
#!/usr/bin/runhaskell
data Avltree a = Leaf | Node a (Avltree a) (Avltree a)
depth Leaf = 0
depth (Node _ l r) = (max (depth l) (depth r)) + 1
getl (Node _ l _) = l
getr (Node _ _ r) = r
getv (Node v _ _) = v
balance t1 t2 = (depth t1) - (depth t2)
balanceLL (Node v (Node lv ll lr) r) = (Node lv ll (Node v lr r))
balanceLR (Node v (Node lv ll (Node rlv rll rrr)) r) = (Node rlv (Node lv ll rll) (Node v rrr r))
balanceRL (Node v l (Node rv (Node lrv lrl lrr) rr)) = (Node lrv (Node v l lrl) (Node rv lrr rr))
balanceRR (Node v l (Node rv rl rr)) = (Node rv (Node v l rl) rr)
insert x Leaf = (Node x Leaf Leaf)
insert x t@(Node v l r)
| x == v = t
| x < v && (balance left_i r) == 2 && x < getv l = balanceLL (Node v left_i r)
| x < v && (balance left_i r) == 2 && x > getv l = balanceLR (Node v left_i r)
| x > v && (balance l right_i) == -2 && x < getv r = balanceRL (Node v l right_i)
| x > v && (balance l right_i) == -2 && x > getv r = balanceRR (Node v l right_i)
| x < v = (Node v left_i r)
| x > v = (Node v l right_i)
where
left_i = insert x l
right_i = insert x r
delete x Leaf = Leaf
delete x (Node v Leaf Leaf) = if v == x then Leaf else (Node v Leaf Leaf)
delete x (Node v l Leaf) = if v == x then l else (Node v l Leaf)
delete x (Node v Leaf r) = if v == x then r else (Node v Leaf r)
delete x (Node v l r)
| v == x = (Node min_v l del_m)
| v > x && abs (balance del_l r) < 2 = (Node v del_l r)
| v < x && abs (balance l del_r) < 2 = (Node v l del_r)
| v > x && (balance (getl r) (getr r)) < 0 = balanceRR (Node v del_l r)
| v < x && (balance (getl l) (getr l)) > 0 = balanceLL (Node v l del_r)
| v > x = balanceRL (Node v del_l r)
| v < x = balanceLR (Node v l del_r)
where
del_m = delete min_v r
del_l = delete x l
del_r = delete x l
min_v = get_min (toList r)
get_min ((x,bal):xs) = x
toList Leaf = []
toList (Node x l r) = (toList l) ++ [(x,balance l r)] ++ (toList r)
isBalanced Leaf = True
isBalanced (Node _ l r) = isBalanced l && isBalanced r && abs (balance l r) < 2
main = print$isBalanced(delete 1 (insert 4(insert 5 (insert 3 (insert 9 (insert 1 Leaf))))))
N
\
N
\
N
a
/ \
b c
p->left?findmin(p->left):p;if( k > p->key )Таким образом, хранение высот с одной стороны не увеличивает объем памяти, отводимой под узлы дерева, а с другой стороны существенно упрощает реализацию некоторых операций.
АВЛ-деревья