atree itemType depthType
::= ALeaf |
ABranch (atree itemType depthType)
itemType
(atree itemType depthType)
depthType;
list a ::= Nil | Cons a (list a);
;;
error = error;
{
add :: Ord a => ATree a -> a -> ATree a
add ALeaf x = ABranch ALeaf x ALeaf 1
add (ABranch l y r hy) x
| y > x = let (ABranch l1 z l2 _) = add l x
in combine l1 (f l1) l2 (f l2) r (f r) z y
| x > y = let (ABranch r1 z r2 _) = add r x
in combine l (f l) r1 (f r1) r2 (f r2) y z
where
f ALeaf = 0
f (ABranch _ _ _ d) = d
}
add tree x
= let
f = \ft -> case ft of ALeaf -> 0; ABranch fl fm fr fd -> fd end
in
case tree of
ALeaf -> ABranch ALeaf x ALeaf 1;
ABranch l y r hy ->
case y > x of
True -> case add l x of ALeaf -> error;
ABranch l1 z l2 dontCare ->
combine l1 (f l1) l2 (f l2) r (f r) z y end;
False -> case add r x of ALeaf -> error;
ABranch r1 z r2 dontCare ->
combine l (f l) r1 (f r1) r2 (f r2) y z end
end
end;
{
combine :: ATree a -> Int ->
ATree a -> Int ->
ATree a -> Int -> a -> a -> ATree a
combine t1 h1 t2 h2 t3 h3 a c
| h2 > h1 && h2 > h3
= ABranch (ABranch t1 a t21 (h1+1)) b (ABranch t22 c t3 (h3+1)) (h1+2)
| h1 >= h2 && h1 >= h3
= ABranch t1 a (ABranch t2 c t3 (max1 h2 h3)) (max1 h1 (max1 h2 h3))
| h3 >= h2 && h3 >= h1
= ABranch (ABranch t1 a t2 (max1 h1 h2)) c t3 (max1 (max1 h1 h2) h3)
where
(ABranch t21 b t22 _) = t2
max1 a b = 1 + (if a > b then a else b)
}
combine t1 h1 t2 h2 t3 h3 a c
= let
max1 = \pp qq -> 1 + (case pp > qq of True -> pp; False -> qq end)
in
case h2 > h1 & h2 > h3 of
True -> case t2 of ABranch t21 b t22 dontCare -> ABranch (ABranch t1 a t21 (h1+1)) b (ABranch t22 c t3 (h3+1)) (h1+2); ALeaf -> error end;
False ->
case h1 >= h2 & h1 >= h3 of
True -> ABranch t1 a (ABranch t2 c t3 (max1 h1 h2)) (max1 h1 (max1 h2 h3));
False -> ABranch (ABranch t1 a t2 (max1 h1 h2)) c t3 (max1 (max1 h1 h2) h3)
end end;
{
toAVL :: Ord a => [a] -> ATree a
toAVL [] = ALeaf
toAVL (x:xs) = add (toAVL xs) x
}
toAVL l
= case l of
Nil -> ALeaf;
Cons x xs -> add (toAVL xs) x
end;
{
maxd :: ATree a -> Int
maxd ALeaf = 0
maxd (ABranch l _ r _) = let dl = maxd l; dr = maxd r
in 1 + (if dl > dr then dl else dr)
}
|