Guest User

Untitled

a guest
May 22nd, 2018
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.85 KB | None | 0 0
  1. import Data.Foldable
  2. import qualified Data.List as L
  3. data Tree a = Node Integer (Tree a) (Tree a) a | Leaf deriving (Show, Eq)
  4. data Path = LeftP | RightP
  5.  
  6.  
  7. instance Foldable Tree where
  8. foldMap f Leaf = mempty
  9. foldMap f (Node _ l r v) = foldMap f l `mappend` f v `mappend` foldMap f r
  10.  
  11. leftRotate :: Tree a -> Tree a
  12. leftRotate (Node tlvl tleft (Node rlvl rleft rright rdata) tdata) =
  13. Node rlvl (Node tlvl tleft rleft tdata) rright rdata
  14. leftRotate tree = tree
  15.  
  16. rightRotate (Node tlvl (Node llvl lleft lright ldata) tright tdata) =
  17. Node llvl lleft (Node tlvl lright tright tdata) ldata
  18. rightRotate tree = tree
  19.  
  20. left :: Tree a -> Tree a
  21. left Leaf = Leaf
  22. left (Node _ left _ _) = left
  23.  
  24. right :: Tree a -> Tree a
  25. right Leaf = Leaf
  26. right (Node _ _ right _) = right
  27.  
  28. level :: Tree a -> Integer
  29. level Leaf = 0
  30. level (Node lvl _ _ _) = lvl
  31.  
  32. isLeaf :: Tree a -> Bool
  33. isLeaf Leaf = True
  34. isLeaf _ = False
  35.  
  36. mapLevel :: (Integer -> Integer) -> Tree a -> Tree a
  37. mapLevel _ Leaf = Leaf
  38. mapLevel f (Node lvl l r d) = Node (f lvl) l r d
  39.  
  40. incLevel :: Tree a -> Tree a
  41. incLevel = mapLevel (1+)
  42.  
  43. decLevel :: Tree a -> Tree a
  44. decLevel = mapLevel (1-)
  45.  
  46. skew :: Tree a -> Tree a
  47. skew tree
  48. | level tree == (level . left) tree = rightRotate tree
  49. | otherwise = tree
  50.  
  51. split :: Tree a -> Tree a
  52. split tree
  53. | level tree == (level . right . right) tree = incLevel . leftRotate $ tree
  54. | otherwise = tree
  55.  
  56. mapAt :: (Tree a -> Tree a) -> [Path] -> Tree a -> Tree a
  57. mapAt f _ Leaf = f Leaf
  58. mapAt f [] t = f t
  59. mapAt f (RightP:xs) (Node lvl l r k) = Node lvl l (mapAt f xs r) k
  60. mapAt f (LeftP:xs) (Node lvl l r k) = Node lvl (mapAt f xs l) r k
  61.  
  62. mapLeft :: (Tree a -> Tree a) -> Tree a -> Tree a
  63. mapLeft f = mapAt f [LeftP]
  64.  
  65. mapRight :: (Tree a -> Tree a) -> Tree a -> Tree a
  66. mapRight f = mapAt f [RightP]
  67.  
  68. insert :: Ord a => a -> Tree a -> Tree a
  69. insert d tree@(Node lvl l r k)
  70. | d < k = split . skew . mapLeft (insert d) $ tree
  71. | d > k = split . skew . mapRight (insert d) $ tree
  72. | otherwise = tree
  73. insert d Leaf = Node 1 Leaf Leaf d
  74.  
  75. predecessor :: Tree a -> Tree a
  76. predecessor = goRight . left
  77. where goRight t
  78. | isLeaf t = t
  79. | (isLeaf . left) t && (isLeaf . right) t = t
  80. | otherwise = goRight . right $ t
  81.  
  82. successor :: Tree a -> Tree a
  83. successor = goLeft . right
  84. where goLeft t
  85. | isLeaf t = t
  86. | (isLeaf . left) t && (isLeaf . right) t = t
  87. | otherwise = goLeft . left $ t
  88.  
  89. deleteRebalance :: Tree a -> Tree a
  90. deleteRebalance Leaf = Leaf
  91. deleteRebalance tree@(Node lvl l r k)
  92. -- If we have some links that jump more than one level.
  93. | level l < newLevel || level r < newLevel =
  94. splitRebalance . skewRebalance . mapLevel (return newLevel) . mapRight adjustRightLevel $ tree
  95. | otherwise = tree
  96. where
  97. newLevel = min ((level . left) tree) ((level . right) tree) + 1
  98. adjustRightLevel = mapLevel (min newLevel)
  99. splitRebalance tree = foldl (flip $ mapAt split) tree $ reverse (L.tails [RightP])
  100. skewRebalance tree = foldl (flip $ mapAt skew) tree $ reverse (L.tails [RightP, RightP])
  101.  
  102.  
  103. delete :: Ord a => a -> Tree a -> Tree a
  104. delete d Leaf = Leaf
  105. delete d tree@(Node lvl left right v)
  106. | level tree == 1 && v == d = Leaf
  107. | d < v = deleteRebalance . mapLeft (delete d) $ tree
  108. | d > v = deleteRebalance . mapRight (delete d) $ tree
  109. | isLeaf left = let (Node _ _ _ v) = successor tree in
  110. deleteRebalance . mapRight (delete v) $ Node lvl left right v
  111. | otherwise = let (Node _ _ _ v) = predecessor tree in
  112. deleteRebalance . mapLeft (delete v) $ Node lvl left right v
  113.  
  114. validTree :: Tree a -> Bool
  115. validTree Leaf = True
  116. validTree tree = (level . left) tree < level tree &&
  117. (level . right) tree <= level tree &&
  118. (level . right . right) tree < level tree &&
  119. validTree (left tree) && validTree (right tree)
Add Comment
Please, Sign In to add comment