使用中序遍历将 haskell 中的树展平
Flattening a tree in haskell using in-order traversal
我想使用我定义的 foldTree 函数实现树的展平,并且按顺序 traversal.Which 应该 return 展平后的列表。
data Tree t = Leaf t
| Tree (Tree t) t (Tree t)
foldTree :: (t1 -> t -> t1 -> t1) -> (t -> t1) -> Tree t -> t1
foldTree treeFn leafFn tree =
case tree of
Leaf v -> leafFn v
Tree leftTree q rightTree -> treeFn (foldTree treeFn leafFn leftTree) q (foldTree treeFn leafFn rightTree)
Input : foldTree (\t1 t t2->t1 + 5*t + t2) (\x->x+9) (Leaf 5)
Expected Output : 14
Input : foldTree (\t1 t t2->t1 + 3*t + t2) (\x->x+5) (Tree (Leaf 3) 2 (Leaf 4))
Expected Output : 23
我尝试了以下代码,但它使用 recursion.I 想从 flattenTree 调用 foldTree 来实现树的展平,而不是对 flatTree 进行递归调用。(在 flattenTree 中使用 foldTree 函数)任何人都可以帮忙告诉我如何整合它。
flatTree :: Tree a -> [a]
flatTree tree =
case tree of
Leaf v -> [v]
Tree p v r -> (flatTree p) ++ [v] ++ (flatTree r)
Input: flatTree (Tree (Leaf 5) 3 (Tree (Leaf 3) 2 (Leaf 4)))
Expected output : [5,3,3,2,4]
看foldTree
的类型。
foldTree :: (b -> a -> b -> b) -> (a -> b) -> Tree a -> b
可以看到b
是变质的结果类型。 foldTree
的工作原理是折叠每个子树以获得每个子树的结果 b
,然后使用折叠函数组合它们。
由于您希望结果是树元素的扁平化列表,我们设置 b ~ [a]
。
foldTree :: ([a] -> a -> [a] -> [a]) -> (a -> [a]) -> Tree a -> [a]
所以 foldTree
的第二个参数应该是将单个元素 a
注入列表 [a]
的东西,第一个应该是将两个列表与一个元素组合在一起的东西做一个更大的清单。
flatTree = foldTree (\xs x ys -> xs ++ x : ys) (\x -> [x])
顺便说一句,GHC 能够为您编写 flatTree
函数,只需查看类型的结构即可。 flatTree :: Tree a -> [a]
匹配 toList :: Foldable f => f a -> [a]
的类型,它是 Foldable
class 的一部分。您需要做的就是说出魔法词 deriving Foldable
,GHC 将吐出一个 Foldable
.
的实例
{-# LANGUAGE DeriveFoldable #-}
data Tree t = Leaf t
| Tree (Tree t) t (Tree t)
deriving Foldable
flatTree :: Tree a -> [a]
flatTree = toList
由于 Tree
构造函数的布局方式,toList
将执行中序遍历。这可以通过调整 Tree
构造函数的定义来改变。
我想使用我定义的 foldTree 函数实现树的展平,并且按顺序 traversal.Which 应该 return 展平后的列表。
data Tree t = Leaf t
| Tree (Tree t) t (Tree t)
foldTree :: (t1 -> t -> t1 -> t1) -> (t -> t1) -> Tree t -> t1
foldTree treeFn leafFn tree =
case tree of
Leaf v -> leafFn v
Tree leftTree q rightTree -> treeFn (foldTree treeFn leafFn leftTree) q (foldTree treeFn leafFn rightTree)
Input : foldTree (\t1 t t2->t1 + 5*t + t2) (\x->x+9) (Leaf 5)
Expected Output : 14
Input : foldTree (\t1 t t2->t1 + 3*t + t2) (\x->x+5) (Tree (Leaf 3) 2 (Leaf 4))
Expected Output : 23
我尝试了以下代码,但它使用 recursion.I 想从 flattenTree 调用 foldTree 来实现树的展平,而不是对 flatTree 进行递归调用。(在 flattenTree 中使用 foldTree 函数)任何人都可以帮忙告诉我如何整合它。
flatTree :: Tree a -> [a]
flatTree tree =
case tree of
Leaf v -> [v]
Tree p v r -> (flatTree p) ++ [v] ++ (flatTree r)
Input: flatTree (Tree (Leaf 5) 3 (Tree (Leaf 3) 2 (Leaf 4)))
Expected output : [5,3,3,2,4]
看foldTree
的类型。
foldTree :: (b -> a -> b -> b) -> (a -> b) -> Tree a -> b
可以看到b
是变质的结果类型。 foldTree
的工作原理是折叠每个子树以获得每个子树的结果 b
,然后使用折叠函数组合它们。
由于您希望结果是树元素的扁平化列表,我们设置 b ~ [a]
。
foldTree :: ([a] -> a -> [a] -> [a]) -> (a -> [a]) -> Tree a -> [a]
所以 foldTree
的第二个参数应该是将单个元素 a
注入列表 [a]
的东西,第一个应该是将两个列表与一个元素组合在一起的东西做一个更大的清单。
flatTree = foldTree (\xs x ys -> xs ++ x : ys) (\x -> [x])
顺便说一句,GHC 能够为您编写 flatTree
函数,只需查看类型的结构即可。 flatTree :: Tree a -> [a]
匹配 toList :: Foldable f => f a -> [a]
的类型,它是 Foldable
class 的一部分。您需要做的就是说出魔法词 deriving Foldable
,GHC 将吐出一个 Foldable
.
{-# LANGUAGE DeriveFoldable #-}
data Tree t = Leaf t
| Tree (Tree t) t (Tree t)
deriving Foldable
flatTree :: Tree a -> [a]
flatTree = toList
由于 Tree
构造函数的布局方式,toList
将执行中序遍历。这可以通过调整 Tree
构造函数的定义来改变。