yapb-0.2.4: src/util/AVL.hs
-- | AVL tree implementation
-- | https://www.cs.uleth.ca/~gaur/code/avl.hs
module AVL(find,ins,Tree(..)) where
data Tree a = Nil | Node !a !(Tree a) !(Tree a)
deriving (Eq,Ord,Show,Read)
find :: Ord a => a -> Tree a -> Bool
find x Nil = False
find x (Node y l r)
| x==y = True
| x<y = find x l
| x>y = find x r
height :: Tree a -> Integer
height Nil = 0
height (Node k l r) = 1 + (max (height l) (height r))
balanced :: Tree a -> Bool
balanced Nil = True
balanced (Node k l r) | not (balanced l) = False
| not (balanced r) = False
| abs ((height l) - (height r)) > 1 = False
| otherwise = True
-- balanced (Node 3 (Node 2 (Node 1 Nil Nil) Nil) Nil)
left :: Tree a -> Tree a
left Nil = error ("left Nil")
left (Node n l r) = l
right :: Tree a -> Tree a
right Nil = error ("right Nil")
right (Node n l r) = r
value :: (Ord a) => Tree a -> a
value Nil = error ("value Nil")-- 0
value (Node n l r) = n
ins :: (Ord a) => Tree a -> a -> Tree a
ins Nil a = Node a Nil Nil
ins (Node b l r) k
| b < k = rotate ((Node b l (ins r k)))
| otherwise = rotate (Node b (ins l k) r)
rotate :: (Ord a) => Tree a -> Tree a
rotate Nil = Nil
rotate (Node n l r)
| not (balanced l) = Node n (rotate l) r
| not (balanced r) = Node n l (rotate r)
| (height l) + 1 < (height r) && -- SR RR
(height (left r)) < (height (right r)) =
Node (value r) (Node n l (left r)) (right r)
| (height r) + 1 < (height l) && -- SR LL
(height (right l)) < (height (left l)) =
Node (value l) (left l) (Node n (right l) r)
| (height l) + 1 < (height r) && -- DR RL
(height (left r)) > (height (right r)) =
Node (value (left r))
(Node n l (left (left r)))
(Node (value r) (right (left r)) (right r))
| (height r) + 1 < (height l) && -- DR LR
(height (right l)) > (height (left l)) =
Node (value (right l))
(Node (value l) (left l) (left (right l)))
(Node n (right (right l)) r)
| otherwise = Node n l r
buildTree :: (Ord a) => [a] -> Tree a
buildTree [] = Nil
buildTree (x:xs) = foldl ins Nil (x:xs)