树的最小高度

时间:2015-10-07 09:18:09

标签: haskell functional-programming

我正在尝试优化代码:

data Tree = Empty | Node Integer Tree Tree
minHeight Empty = -1
minHeight (Node _ Empty Empty) = 0
minHeight (Node _ l     r    ) = (min (minHeight l) (minHeight r)) + 1

我的目标是不计算深度将高于已知分支的分支。

3 个答案:

答案 0 :(得分:14)

你可以使用Peano Nat而不是Integer来让懒惰做这项工作:

data Nat = S Nat | Z deriving (Eq)

instance Ord Nat where
    min (S n) (S m) = S (min n m)
    min  _     _    = Z

instance Enum Nat where
    fromEnum  Z    = 0
    fromEnum (S n) = fromEnum n + 1

data Tree = Empty | Node Integer Tree Tree

minHeight  Empty        = Z
minHeight (Node _  l r) = S (min (minHeight l) (minHeight r))

tree = Node 0 (Node 1 tree Empty) tree

main = print $ fromEnum $ minHeight tree -- 2

答案 1 :(得分:2)

您希望从顶部开始计算深度,并使用minHeight的返回值绑定其他调用。

minHeight :: Integer -> (Maybe Integer) -> Tree -> Integer
minHeight depth bound tree = ...

最初传入0作为深度,Nothing作为绑定(又名Infinity),在树叶处返回较小的depthbound,否则看看你是否有有限界限(Just b)并将其与当前depth进行比较。

case b of
    Just min -> if min <= depth then return min else RECURSION
    otherwise -> RECURSION

每当您在递归中计算某些minHeight时,请将其结果与当前bound合并。

minHeight d min (Node _ t1 t2) =
    let min1 = Just (minHeight (d + 1) min t1) in
        (minHeight (d + 1) min1 t2)

答案 2 :(得分:2)

这是一个解决方案,它不会计算分支,其深度将高于已知的分支:

data Tree = Empty | Node Integer Tree Tree

minHeight :: Tree -> Int
minHeight =
  loop Nothing 0
  where
    loop defaultDepth depth tree =
      case defaultDepth of
        Just x | x <= depth ->
          x
        _ ->
          case tree of
            Empty -> depth
            Node _ left right ->
              loop (Just (loop defaultDepth (succ depth) left)) (succ depth) right