我正在尝试优化代码:
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
我的目标是不计算深度将高于已知分支的分支。
答案 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
),在树叶处返回较小的depth
和bound
,否则看看你是否有有限界限(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