在BST中查找下一个节点

时间:2018-11-18 23:22:12

标签: haskell

是否有更优雅的方法来做到这一点?我的解决方案并不特别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"

0 个答案:

没有答案