【问题标题】:Transform a tree in Haskell在 Haskell 中转换一棵树
【发布时间】:2020-02-05 15:34:17
【问题描述】:
data BinaryTree a = Null | Node (BinaryTree a) a (BinaryTree a)
deriving Show
data RoseTree a = RoseNode a [RoseTree a]
deriving Show
binaryTreeToRose :: BinaryTree a -> RoseTree a
binaryTreeToRose btree = case btree of
Node Null a Null -> RoseNode a []
Node left a Null -> RoseNode a [binaryTreeToRose left]
Node Null a right -> RoseNode a [binaryTreeToRose right]
Node left a right -> RoseNode a [binaryTreeToRose left]++[binaryTreeToRose right]
我尝试在 Haskell 中编写一个将二叉树转换为玫瑰树的函数。但我不知道如何用递归解决这个问题。
【问题讨论】:
标签:
haskell
recursion
tree
binary-tree
【解决方案1】:
您已经在递归地解决这个问题。实际上,您在孩子left 和right 上调用binaryTreeToRose。因此,您根据自身定义 binaryTreeToRose。
但是,您的功能并不全面。因为对于binaryTreeToRose Null,它会出错。我们可以将返回类型设为Maybe (RoseTree a):
import Data.Maybe(catMaybes)
binaryTreeToRose :: BinaryTree a -> Maybe (RoseTree a)
binaryTreeToRose Null = Nothing
binaryTreeToRose (Node l a r) = Just (RoseNode a (catMaybes (map binaryTreeToRose [l, r])))
甚至更短:
import Data.Maybe(mapMaybe)
binaryTreeToRose :: BinaryTree a -> Maybe (RoseTree a)
binaryTreeToRose Null = Nothing
binaryTreeToRose (Node l a r) = Just (RoseNode a (mapMaybe binaryTreeToRose [l, r]))
【解决方案2】:
改变
[binaryTreeToRose left]++[binaryTreeToRose right]
(无论如何,这是一个错误)在您的最后一行代码中
(binaryTreeToRose left ++ binaryTreeToRose right)
,将函数的类型改为
binaryTreeToRose :: BinaryTree a -> [RoseTree a]
并相应地修改其他情况(还为Null 情况添加一个新子句)。
您的BinaryTree 可以为空(由Null 表示),但RoseTree 不能。这意味着我们不能将前者转换为后者,而是转换为它们的 list。
Haskell 库将类型 [RoseTree a] 称为 “Forest”。所以转换的结果将是一个玫瑰树森林,包含其中之一或零个(代表空二叉树的情况)。
拥有一棵空树就像根本没有树。两种方式都没有水果。
【解决方案3】:
如果你想玩得开心,你可以使用递归方案进行递归。在这种情况下,递归方案通过提供一层推导来提供自动递归。
例如:
data BT a = BNil | BN (BT a) a (BT a)
deriving Show
data RT a = RN a [RT a]
deriving Show
-- data BTF a f = BNilF | BNF f a f deriving Functor
makeBaseFunctor ''BT --BinaryTree
-- binaryTreeToRose :: BinaryTree a -> Maybe (RoseTree a)
binaryTreeToRose :: BT a -> Maybe (RT a)
binaryTreeToRose = cata alg where
alg BNilF = Nothing
alg BNF l a r = Just $ RN a $ catMaybes (l ++ r)