fork(1) download
  1. {-# LANGUAGE NoMonomorphismRestriction #-}
  2.  
  3. data Map k a = Tip | Bin Size k a (Map k a) (Map k a)
  4. deriving (Eq, Show)
  5.  
  6. type Size = Int
  7.  
  8. size :: Map k a -> Int
  9. size t
  10. = case t of
  11. Tip -> 0
  12. Bin sz _ _ _ _ -> sz
  13.  
  14. ----------------------------------------------------------------
  15.  
  16. -- basic rotations
  17. singleL, singleR :: a -> b -> Map a b -> Map a b -> Map a b
  18. singleL k1 x1 t1 (Bin _ k2 x2 t2 t3) = bin k2 x2 (bin k1 x1 t1 t2) t3
  19. singleR k1 x1 (Bin _ k2 x2 t1 t2) t3 = bin k2 x2 t1 (bin k1 x1 t2 t3)
  20.  
  21. doubleL, doubleR :: a -> b -> Map a b -> Map a b -> Map a b
  22. doubleL k1 x1 t1 (Bin _ k2 x2 (Bin _ k3 x3 t2 t3) t4) = bin k3 x3 (bin k1 x1 t1 t2) (bin k2 x2 t3 t4)
  23. doubleR k1 x1 (Bin _ k2 x2 t1 (Bin _ k3 x3 t2 t3)) t4 = bin k3 x3 (bin k2 x2 t1 t2) (bin k1 x1 t3 t4)
  24.  
  25. ----------------------------------------------------------------
  26.  
  27. bin :: k -> a -> Map k a -> Map k a -> Map k a
  28. bin k x l r
  29. = Bin (size l + size r + 1) k x l r
  30.  
  31. singleton :: k -> a -> Map k a
  32. singleton k x
  33. = Bin 1 k x Tip Tip
  34.  
  35. isBalanced :: Map k a -> Map k a -> Bool
  36. isBalanced a b = 3 * x >= y
  37. where
  38. x = size a + 1
  39. y = size b + 1
  40.  
  41. isSingle :: Map k a -> Map k a -> Bool
  42. isSingle a b = z < 2 * w
  43. where
  44. z = size a + 1
  45. w = size b + 1
  46.  
  47. ----------------------------------------------------------------
  48. balanceL :: k -> a -> Map k a -> Map k a -> Map k a
  49. balanceL k x l r
  50. | isBalanced l r = bin k x l r
  51. | otherwise = rotateL k x l r
  52.  
  53. balanceR :: k -> a -> Map k a -> Map k a -> Map k a
  54. balanceR k x l r
  55. | isBalanced r l = bin k x l r
  56. | otherwise = rotateR k x l r
  57.  
  58. balance :: k -> a -> Map k a -> Map k a -> Map k a
  59. balance k x l r
  60. | isBalanced l r && isBalanced r l = bin k x l r
  61. | size l > size r = rotateR k x l r
  62. | otherwise = rotateL k x l r
  63.  
  64. ----------------------------------------------------------------
  65.  
  66. rotateL :: a -> b -> Map a b -> Map a b -> Map a b
  67. rotateL k x l r@(Bin _ _ _ rl rr)
  68. | isSingle rl rr = singleL k x l r
  69. | otherwise = doubleL k x l r
  70.  
  71. rotateR :: a -> b -> Map a b -> Map a b -> Map a b
  72. rotateR k x l@(Bin _ _ _ ll lr) r
  73. | isSingle lr ll = singleR k x l r
  74. | otherwise = doubleR k x l r
  75.  
  76. ----------------------------------------------------------------
  77.  
  78. join :: Ord k => k -> a -> Map k a -> Map k a -> Map k a
  79. join kx x Tip r = insertMin kx x r
  80. join kx x l Tip = insertMax kx x l
  81. join kx x l@(Bin _ ky y ly ry) r@(Bin _ kz z lz rz)
  82. | bal1 && bal2 = bin kx x l r
  83. | bal1 = balanceL ky y ly (join kx x ry r)
  84. | otherwise = balanceR kz z (join kx x l lz) rz
  85. where
  86. bal1 = isBalanced l r
  87. bal2 = isBalanced r l
  88.  
  89. merge :: Map k a -> Map k a -> Map k a
  90. merge Tip r = r
  91. merge l Tip = l
  92. merge l@(Bin _ kx x lx rx) r@(Bin _ ky y ly ry)
  93. | bal1 && bal2 = glue l r
  94. | bal1 = balanceL kx x lx (merge rx r)
  95. | otherwise = balanceR ky y (merge l ly) ry
  96. where
  97. bal1 = isBalanced l r
  98. bal2 = isBalanced r l
  99.  
  100. ----------------------------------------------------------------
  101.  
  102. insertMax,insertMin :: k -> a -> Map k a -> Map k a
  103. insertMax kx x t
  104. = case t of
  105. Tip -> singleton kx x
  106. Bin _ ky y l r
  107. -> balanceL ky y l (insertMax kx x r)
  108.  
  109. insertMin kx x t
  110. = case t of
  111. Tip -> singleton kx x
  112. Bin _ ky y l r
  113. -> balanceR ky y (insertMin kx x l) r
  114.  
  115. ----------------------------------------------------------------
  116.  
  117. glue :: Map k a -> Map k a -> Map k a
  118. glue Tip r = r
  119. glue l Tip = l
  120. glue l r
  121. | size l > size r = let ((km,m),l') = deleteFindMax l in balanceL km m l' r
  122. | otherwise = let ((km,m),r') = deleteFindMin r in balanceR km m l r'
  123.  
  124. -- | /O(log n)/. Delete and find the minimal element.
  125. --
  126. -- > deleteFindMin (fromList [(5,"a"), (3,"b"), (10,"c")]) == ((3,"b"), fromList[(5,"a"), (10,"c")])
  127. -- > deleteFindMin Error: can not return the minimal element of an empty map
  128.  
  129. deleteFindMin :: Map k a -> ((k,a),Map k a)
  130. deleteFindMin t
  131. = case t of
  132. Bin _ k x Tip r -> ((k,x),r)
  133. Bin _ k x l r -> let (km,l') = deleteFindMin l in (km,balance k x l' r)
  134. Tip -> (error "Map.deleteFindMin: can not return the minimal element of an empty map", Tip)
  135.  
  136. -- | /O(log n)/. Delete and find the maximal element.
  137. --
  138. -- > deleteFindMax (fromList [(5,"a"), (3,"b"), (10,"c")]) == ((10,"c"), fromList [(3,"b"), (5,"a")])
  139. -- > deleteFindMax empty Error: can not return the maximal element of an empty map
  140.  
  141. deleteFindMax :: Map k a -> ((k,a),Map k a)
  142. deleteFindMax t
  143. = case t of
  144. Bin _ k x l Tip -> ((k,x),l)
  145. Bin _ k x l r -> let (km,r') = deleteFindMax r in (km,balance k x l r')
  146. Tip -> (error "Map.deleteFindMax: can not return the maximal element of an empty map", Tip)
  147.  
  148. ----------------------------------------------------------------
  149.  
  150. balanced :: Map k a -> Bool
  151. balanced Tip = True
  152. balanced (Bin _ _ _ l r) = isBalanced l r && isBalanced r l && balanced l && balanced r
  153.  
  154. push k a = glue a $ singleton k k
  155.  
  156. g = show . map balanced
  157.  
  158. main = putStrLn $ g $ scanl (\t n -> push n t) Tip [0..7]
Success #stdin #stdout 0.01s 5532KB
stdin
Standard input is empty
stdout
[True,True,True,True,True,True,True,True,False]