是否有更优雅的方法来做到这一点?我的解决方案并不特别Haskell-y。
我还写了一个版本,其中节点没有父指针,但是效率较低。
{-# LANGUAGE GADTs #-}
module BST (next) where
-- Define BST datatype
data BST a where
Nil :: BST a
Node :: (Eq a, Ord a) => (BST a) -> a -> (BST a) -> (BST a) -> (BST a)
instance Eq (BST a) where
Nil == Nil = True
Nil == _ = False
_ == Nil = False
(Node _ a _ _) == (Node _ b _ _) = a == b
instance (Show a) => Show (BST a) where
show Nil = ""
show (Node l v r _) = "(" ++ show v ++ ")"
-- Accessors
left :: BST a -> BST a
left Nil = Nil
left (Node Nil _ _ _) = Nil
left (Node l _ _ _) = l
-- Utility functions
min :: BST a -> BST a
min Nil = Nil
min n@(Node Nil _ _ _) = n
min (Node l _ _ _) = BST.min l
-- Traverse up, until we find a parent node that has a value larger than a.
bigParent :: a -> BST a -> BST a
bigParent _ Nil = Nil
bigParent a p@(Node _ pa _ pp)
| pa > a = p
| otherwise = bigParent a pp
-- Next node
next :: BST a -> BST a
next Nil = Nil
next (Node _ _ r@Node{} _) = BST.min r
next n@(Node _ a _ p)
| n == left p = p
| otherwise = bigParent a p
-- Tests
-- 8
-- / \
-- 3 10
-- / \ \
-- 1 6 14
-- / \ /
-- 4 7 13
n1 = Node Nil 1 Nil n3
n4 = Node Nil 4 Nil n6
n7 = Node Nil 7 Nil n6
n6 = Node n4 6 n7 n3
n3 = Node n1 3 n6 n8
n13 = Node Nil 13 Nil n14
n14 = Node n13 14 Nil n10
n10 = Node Nil 10 n14 n8
n8 = Node n3 8 n10 Nil
main = do
expect "n1" (next n1) n3
expect "n3" (next n3) n4
expect "n4" (next n4) n6
expect "n6" (next n6) n7
expect "n7" (next n7) n8
expect "n8" (next n8) n10
expect "n10" (next n10) n13
expect "n13" (next n13) n14
expect :: Eq a => String -> a -> a -> IO ()
expect name actual expected = case actual == expected of
True -> putStrLn $ "[" ++ name ++ "] OK"
False -> putStrLn $ "[" ++ name ++ "] FAIL"