module Data.RBTree.LeftLeaning (
insert
, delete
, deleteMin
, deleteMax
, balanceL
, balanceR
, valid
) where
import Data.RBTree.Internal
import Prelude hiding (minimum, maximum)
valid :: Ord a => RBTree a -> Bool
valid t = isBalanced t && isLeftLean t && blackHeight t && isOrdered t
isLeftLean :: RBTree a -> Bool
isLeftLean Leaf = True
isLeftLean (Node B _ _ _ (Node R _ _ _ _)) = False
isLeftLean (Node _ _ r _ l) = isLeftLean r && isLeftLean l
insert :: Ord a => a -> RBTree a -> RBTree a
insert kx t = turnB (insert' kx t)
insert' :: Ord a => a -> RBTree a -> RBTree a
insert' kx Leaf = Node R 1 Leaf kx Leaf
insert' kx t@(Node c h l x r) = case compare kx x of
LT -> balanceL c h (insert' kx l) x r
GT -> balanceR c h l x (insert' kx r)
EQ -> t
balanceL :: Color -> BlackHeight -> RBTree a -> a -> RBTree a -> RBTree a
balanceL B h (Node R _ ll@(Node R _ _ _ _) lx lr) x r =
Node R (h+1) (turnB ll) lx (Node B h lr x r)
balanceL c h l x r = Node c h l x r
balanceR :: Color -> BlackHeight -> RBTree a -> a -> RBTree a -> RBTree a
balanceR B h l@(Node R _ _ _ _) x r@(Node R _ _ _ _) =
Node R (h+1) (turnB l) x (turnB r)
balanceR c h l x (Node R rh rl rx rr) = Node c h (Node R rh l x rl) rx rr
balanceR c h l x r = Node c h l x r
deleteMin :: RBTree a -> RBTree a
deleteMin t = case deleteMin' (turnR t) of
Leaf -> Leaf
s -> turnB s
deleteMin' :: RBTree a -> RBTree a
deleteMin' (Node R _ Leaf _ Leaf) = Leaf
deleteMin' t@(Node R h l x r)
| isRed l = Node R h (deleteMin' l) x r
| isBB && isBR = hardMin t
| isBB = balanceR B (h1) (deleteMin' (turnR l)) x (turnR r)
| otherwise = Node R h (Node B lh (deleteMin' ll) lx lr) x r
where
isBB = isBlackLeftBlack l
isBR = isBlackLeftRed r
Node B lh ll lx lr = l
deleteMin' _ = error "deleteMin'"
hardMin :: RBTree a -> RBTree a
hardMin (Node R h l x (Node B rh (Node R _ rll rlx rlr) rx rr))
= Node R h (Node B rh (deleteMin' (turnR l)) x rll)
rlx
(Node B rh rlr rx rr)
hardMin _ = error "hardMin"
deleteMax :: RBTree a -> RBTree a
deleteMax t = case deleteMax' (turnR t) of
Leaf -> Leaf
s -> turnB s
deleteMax' :: RBTree a -> RBTree a
deleteMax' (Node R _ Leaf _ Leaf) = Leaf
deleteMax' t@(Node R h l x r)
| isRed l = rotateR t
| isBB && isBR = hardMax t
| isBB = balanceR B (h1) (turnR l) x (deleteMax' (turnR r))
| otherwise = Node R h l x (rotateR r)
where
isBB = isBlackLeftBlack r
isBR = isBlackLeftRed l
deleteMax' _ = error "deleteMax'"
rotateR :: RBTree a -> RBTree a
rotateR (Node c h (Node R _ ll lx lr) x r) = balanceR c h ll lx (deleteMax' (Node R h lr x r))
rotateR _ = error "rorateR"
hardMax :: RBTree a -> RBTree a
hardMax (Node R h (Node B lh ll@(Node R _ _ _ _ ) lx lr) x r)
= Node R h (turnB ll) lx (balanceR B lh lr x (deleteMax' (turnR r)))
hardMax _ = error "hardMax"
delete :: Ord a => a -> RBTree a -> RBTree a
delete kx t = case delete' kx (turnR t) of
Leaf -> Leaf
t' -> turnB t'
delete' :: Ord a => a -> RBTree a -> RBTree a
delete' _ Leaf = Leaf
delete' kx (Node c h l x r) = case compare kx x of
LT -> deleteLT kx c h l x r
GT -> deleteGT kx c h l x r
EQ -> deleteEQ kx c h l x r
deleteLT :: Ord a => a -> Color -> BlackHeight -> RBTree a -> a -> RBTree a -> RBTree a
deleteLT kx R h l x r
| isBB && isBR = Node R h (Node B rh (delete' kx (turnR l)) x rll) rlx (Node B rh rlr rx rr)
| isBB = balanceR B (h1) (delete' kx (turnR l)) x (turnR r)
where
isBB = isBlackLeftBlack l
isBR = isBlackLeftRed r
Node B rh (Node R _ rll rlx rlr) rx rr = r
deleteLT kx c h l x r = Node c h (delete' kx l) x r
deleteGT :: Ord a => a -> Color -> BlackHeight -> RBTree a -> a -> RBTree a -> RBTree a
deleteGT kx c h (Node R _ ll lx lr) x r = balanceR c h ll lx (delete' kx (Node R h lr x r))
deleteGT kx R h l x r
| isBB && isBR = Node R h (turnB ll) lx (balanceR B lh lr x (delete' kx (turnR r)))
| isBB = balanceR B (h1) (turnR l) x (delete' kx (turnR r))
where
isBB = isBlackLeftBlack r
isBR = isBlackLeftRed l
Node B lh ll@(Node R _ _ _ _) lx lr = l
deleteGT kx R h l x r = Node R h l x (delete' kx r)
deleteGT _ _ _ _ _ _ = error "deleteGT"
deleteEQ :: Ord a => a -> Color -> BlackHeight -> RBTree a -> a -> RBTree a -> RBTree a
deleteEQ _ R _ Leaf _ Leaf = Leaf
deleteEQ kx c h (Node R _ ll lx lr) x r = balanceR c h ll lx (delete' kx (Node R h lr x r))
deleteEQ _ R h l _ r
| isBB && isBR = balanceR R h (turnB ll) lx (balanceR B lh lr m (deleteMin' (turnR r)))
| isBB = balanceR B (h1) (turnR l) m (deleteMin' (turnR r))
where
isBB = isBlackLeftBlack r
isBR = isBlackLeftRed l
Node B lh ll@(Node R _ _ _ _) lx lr = l
m = minimum r
deleteEQ _ R h l _ r@(Node B rh rl rx rr) = Node R h l m (Node B rh (deleteMin' rl) rx rr)
where
m = minimum r
deleteEQ _ _ _ _ _ _ = error "deleteEQ"