insert :: (Ord a) => a -> RBTree a -> RBTree a insert v t = blacken $ ins t where ins E = TRE v E ins (T c l x r) = case compare v x of LT -> balance c (ins l) x r EQ -> T c l x r GT -> balance c l x (ins r)
为什么插入Red节点?是为了不破坏性质3,这样插入只可能破坏性质2。
对于性质2的破坏(出现连续Red),显然有且仅有4种情况:左左、左右、右左、右右。
1 2 3 4 5 6 7 8 9 10 11
dataColor = R | Bderiving (Show, Enum) dataRBTree a = E | TColor (RBTreea) a (RBTreea)
balance :: Color -> RBTree a -> a -> RBTree a -> RBTree a
balanceB (TR (TR a x b) y c) z d = TR (TB a x b) y (TB c z d) balanceB (TR a x (TR b y c)) z d = TR (TB a x b) y (TB c z d) balanceB a x (TR (TR b y c) z d) = TR (TB a x b) y (TB c z d) balanceB a x (TR b y (TR c z d)) = TR (TB a x b) y (TB c z d)
bubble :: Color -> RBTree a -> a -> RBTree a -> RBTree a bubble c l x r | isBB l || isBB r = balance (blacker c) (redder' l) x (redder' r) | otherwise = balance c l x r
balance :: Color -> RBTree a -> a -> RBTree a -> RBTree a
balanceB (TR (TR a x b) y c) z d = TR (TB a x b) y (TB c z d) balanceB (TR a x (TR b y c)) z d = TR (TB a x b) y (TB c z d) balanceB a x (TR (TR b y c) z d) = TR (TB a x b) y (TB c z d) balanceB a x (TR b y (TR c z d)) = TR (TB a x b) y (TB c z d)
balanceBB a x (TR b y (TR c z d)) = TB (TB a x b) y (TB c z d) balanceBB a x (TR (TR b y c) z d) = TB (TB a x b) y (TB c z d) balanceBB (TR (TR a x b) y c) z d = TB (TB a x b) y (TB c z d) balanceBB (TR a x (TR b y c)) z d = TB (TB a x b) y (TB c z d)
balanceBB a x (TNB b y (TB c z d)) = TB (balance B a x (redder' b)) y (TB c z d) balanceBB (TNB (TB a x b) y c) z d = TB (TB a x b) y (balance B (redder' c) z d)
delete :: (Ord a) => a -> RBTree a -> RBTree a delete v t = blacken $ del t where del E = E del t@(T c l x r) = case compare v x of LT -> bubble c (del l) x r GT -> bubble c l x (del r) EQ -> remove t
remove :: RBTree a -> RBTree a remove (TRE _ E) = E remove (TBE _ E) = EE remove (TBE _ (TR l x r)) = TB l x r remove (TB (TR l x r) _ E) = TB l x r remove (T c l x r) = bubble c l' x' r where l' = removeMax l x' = findMax l
removeMax :: RBTree a -> RBTree a removeMax t@(T _ _ _ E) = remove t removeMax (T c l x r) = bubble c l x (removeMax r)
findMax :: RBTree a -> a findMaxE = error "findMax in an empty tree" findMax (T _ _ x E) = x findMax (T _ _ _ r) = findMax r
blacken :: RBTree a -> RBTree a blacken (T _ l x r) = TB l x r blacken _ = E
redden :: RBTree a -> RBTree a redden (T _ l x r) = TR l x r
balance :: Color -> RBTree a -> a -> RBTree a -> RBTree a
balanceB (TR (TR a x b) y c) z d = TR (TB a x b) y (TB c z d) balanceB (TR a x (TR b y c)) z d = TR (TB a x b) y (TB c z d) balanceB a x (TR (TR b y c) z d) = TR (TB a x b) y (TB c z d) balanceB a x (TR b y (TR c z d)) = TR (TB a x b) y (TB c z d)
balanceBB a x (TR b y (TR c z d)) = TB (TB a x b) y (TB c z d) balanceBB a x (TR (TR b y c) z d) = TB (TB a x b) y (TB c z d) balanceBB (TR (TR a x b) y c) z d = TB (TB a x b) y (TB c z d) balanceBB (TR a x (TR b y c)) z d = TB (TB a x b) y (TB c z d)
balanceBB a x (TNB b y (TB c z d)) = TB (balance B a x (redder' b)) y (TB c z d) balanceBB (TNB (TB a x b) y c) z d = TB (TB a x b) y (balance B (redder' c) z d)
balance c l x r = T c l x r
bubble :: Color -> RBTree a -> a -> RBTree a -> RBTree a bubble c l x r | isBB l || isBB r = balance (blacker c) (redder' l) x (redder' r) | otherwise = balance c l x r
insert :: (Ord a) => a -> RBTree a -> RBTree a insert v t = blacken $ ins t where ins E = TRE v E ins (T c l x r) = case compare v x of LT -> balance c (ins l) x r EQ -> T c l x r GT -> balance c l x (ins r)
delete :: (Ord a) => a -> RBTree a -> RBTree a delete v t = blacken $ del t where del E = E del t@(T c l x r) = case compare v x of LT -> bubble c (del l) x r GT -> bubble c l x (del r) EQ -> remove t
remove :: RBTree a -> RBTree a remove (TRE _ E) = E remove (TBE _ E) = EE remove (TBE _ (TR l x r)) = TB l x r remove (TB (TR l x r) _ E) = TB l x r remove (T c l x r) = bubble c l' x' r where l' = removeMax l x' = findMax l
removeMax :: RBTree a -> RBTree a removeMax t@(T _ _ _ E) = remove t removeMax (T c l x r) = bubble c l x (removeMax r)
findMax :: RBTree a -> a findMaxE = error "findMax in an empty tree" findMax (T _ _ x E) = x findMax (T _ _ _ r) = findMax r
lookup :: (Ord a) => a -> RBTree a -> Maybe a lookup _ E = Nothing lookup a (T _ l x r) = case compare a x of LT -> lookup a l GT -> lookup a r EQ -> Just x
---
showTree :: (Show a) => RBTree a -> Doc showTreeE = text "E" showTree (T c l x r) = text "T" <+> text (show c) <+> text (show x) $+$ (text " " <+> vcat [showTree l, showTree r]) instance (Showa) => Show (RBTreea) where show = render . showTree instanceFoldableRBTreewhere foldMap f E = mempty foldMap f (T _ l x r) = foldMap f l `mappend` f x `mappend` foldMap f r
toList :: RBTree a -> [a] toList = foldr (:) []
fromList :: (Foldable t, Ord a) => t a -> RBTree a fromList = foldr insert E