我一直在玩Haskell中的二叉树,我正在尝试实现一个dfs变体,该变量将从根节点返回到包含搜索值的节点的路径(由left和rights组成)。我认为最好返回Maybe Directions
类型。
到目前为止已实施的内容。
data Tree a = Empty | Node a (Tree a) (Tree a)
deriving (Show, Eq)
data Direction = L | R
deriving (Show)
type Directions = [Direction]
inTree :: (Eq a) => a -> Tree a -> [Direction]
inTree val (Node x l r)
| val == x = []
| l /= Empty = L:(inTree val l)
| r /= Empty = R:(inTree val r)
| otherwise =
但我不知道如何让它遍历整棵树。我觉得我可能会过于强迫地思考。
答案 0 :(得分:4)
您使用Maybe Direction
的想法很好。我会按如下方式重写你的函数:
inTree :: (Eq a) => a -> Tree a -> Maybe [Direction]
inTree val Empty = Nothing
inTree val (Node x l r)
| val == x = Just []
| otherwise = (fmap (L:) (inTree val l)) <|> (fmap (R:) (inTree val r))
如果原始值为fmap
,则f
Maybe
Nothing
会导致Nothing
Just (f v)
Just v
Just [Direction]
Direction
<|>
Just [Direction]
1}}。在我们的例子中,如果递归调用找到了值(因此它返回路径x
),我们追加我们在当前节点处获取的{{1}}。
{{1}}运算符来自Alternative
instance of Maybe
。这是对maybes左偏的选择。在这里,我们使用它来选择返回{{1}}的子树(如果有的话)。
一个很好的练习是修改代码,使其返回树中{{1}}的所有路径。
答案 1 :(得分:0)
这是一个不太精简的版本,类似于问题中提出的样式。这对于学习 Haskell 且尚未理解 Control.Applicative
库内容的任何人来说可能很有用。
inTree :: Eq a => a -> Tree a -> Maybe [Direction]
inTree _ Empty = Nothing
inTree val (Node x l r)
| val == x = Just []
| otherwise = case inTree val l of Just ys -> Just (L : ys)
Nothing -> case inTree val r of Just ys -> Just (R : ys)
Nothing -> Nothing