Advertisement
Guest User

AVL-tree

a guest
Apr 27th, 2015
247
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. module AVL where
  2.  
  3. -- map based on balanced AVL-tree
  4. data AVL k v = Leaf | Node k v (AVL k v) (AVL k v) Int deriving (Show)
  5.  
  6. -- это в кр не надо, просто функция вывода дерева в консоль
  7. pp :: Show k => AVL k v -> IO ()
  8. pp = (mapM_ putStrLn) . treeIndent
  9.   where
  10.     treeIndent Leaf           = ["-- /-"]
  11.     treeIndent (Node k v lb rb _) =
  12.       ["--" ++ (show k)] ++
  13.       map ("  |" ++) ls ++
  14.       ("  `" ++ r) : map ("   " ++) rs
  15.       where
  16.         (r:rs) = treeIndent $ rb
  17.         ls     = treeIndent $ lb
  18.  
  19. height :: AVL k v -> Int
  20. height Leaf             = 0
  21. height (Node _ _ _ _ h) = h
  22.  
  23. maxHeight :: AVL k v -> AVL k v -> Int
  24. maxHeight t1 t2 = 1 + max (height t1) (height t2)
  25.  
  26. balance :: AVL k v -> Int
  27. balance Leaf = 0
  28. balance (Node _ _ l r _) = height l - height r
  29.  
  30. rotateLeft :: AVL k v -> AVL k v
  31. rotateLeft (Node kx vx l (Node ky vy rl rr _) _) =
  32.     Node ky vy newLeft rr (maxHeight newLeft rr)
  33.     where newLeft = Node kx vx l rl (maxHeight l rl)
  34.  
  35. rotateRight :: AVL k v -> AVL k v
  36. rotateRight (Node kx vx (Node ky vy ll lr _) r _) =
  37.     Node ky vy ll newRight (maxHeight ll newRight)
  38.     where newRight = Node kx vx lr r (maxHeight lr r)
  39.  
  40. rebalance :: AVL k v -> AVL k v
  41. rebalance t@(Node k v l r _)
  42.     | (balance t == -2) && (balance r <= 0) = rotateLeft t -- small left rotation
  43.     | (balance t == 2) && (balance l >= 0) = rotateRight t -- small right rotation
  44.     | (balance t == -2) && (balance r == 1) = rotateLeft (Node k v l (rotateRight r) 0) -- big left rotation
  45.     | (balance t == 2) && (balance l == -1) = rotateRight (Node k v (rotateLeft l) r 0) -- big right rotation
  46.     | otherwise = t
  47.  
  48. insertAVL :: (Ord k) => k -> v -> AVL k v -> AVL k v
  49. insertAVL k v Leaf = Node k v Leaf Leaf 1
  50. insertAVL k v (Node k' v' l r h)
  51.     | k < k'  = let newLeft = insertAVL k v l in rebalance $ Node k' v' newLeft r (maxHeight newLeft r)
  52.    | k > k'  = let newRight = insertAVL k v r in rebalance $ Node k' v' l newRight (maxHeight l newRight)
  53.     | k == k' = Node k' v l r h
  54.    
  55. -- примеры работы; можно запустить в консоли pp t1 и посмотреть, что действительно сбалансированное дерево      
  56. t1 = foldr (\t -> insertAVL (fst t) (snd t)) Leaf (zip [1..10] [1..10])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement