Haskell树列表

时间:2010-11-08 17:45:17

标签: list haskell tree

哈斯克尔,我们走吧!好的,这里是目前使用的代码示例:

data Tree a = Node (Tree a) (Tree a) | Leaf a | Empty  deriving (Show)
main = do
let my_tree = Node (Node (Leaf [1,2,4,9]) (Leaf [3,5,5,8,5])) (Leaf [2,7,5,5,2])
cc my_tree
bb my_tree  
aa my_tree
cc my_tree  
print("Done")

只需创建一个包含Int列表的树,需要3个函数来处理aa,bb,cc:

cc - 只输出一棵树 bb - 广告到每个值+2
aa - 输出每个值的列表,如:[length,minimum,maximum]

现在有一个代码可以完成所有这些,我把它放在键盘中(问我是否需要):http://codepad.org/ ??????? 现在你可以看到aa的最后一个输出也是一棵树 它可能是一个快速修复,但我无法弄明白 - 所以aa输出的不是树而是列出[]这些:

[length param,minimum param,maximum param]

换句话说,有人知道如何将其作为列表输出,而不是在树内输出吗? 所以在输出而不是:

Node (Node (Leaf [4,1,9]) (Leaf [6,0,8])) (Leaf [5,2,7])

将是

[[4,1,9],[6,0,8],[5,2,7]]

我认为必须在这里修改一些内容:

fmap3 ff (Node l r) = Node (fmap2 ff l) (fmap2 ff r)
fmap3 ff (Leaf x) = Leaf (ff x) 

任何人??

2 个答案:

答案 0 :(得分:1)

您正在尝试执行reduce操作:将树转换为单个值(三次:length,maximum,minimum)。使用map函数无法完成此操作,因为按定义映射始终将树转换为树。

典型的reduce算法使用函数将两个简化结果“合并”在一起,并递归地合并树中任何位置获得的结果。所以,你会有这样的事情:

reduce ff (Node l r) = ff (reduce ff l) (reduce ff r)
reduce ff (Leaf x)   = x

完成此操作后,您可以使用map函数将您的树(无论如何)转换为要减少的值树,并应用reduce函数。

cc tree = [ reduce (+)   (fmap2 length tree) , 
            reduce (min) (fmap2 minimum tree) ,
            reduce (max) (fmap2 maximum tree) ]

编辑:我在回答时已经改变了你的问题。您可以使用上面的缩减功能和列表连接功能++来完成此操作,但列表连接在性能方面不是很性感。

通过使用带累加器参数的遍历,有一种惯用的方法可以将树转换为列表:

traverse init (Node l r) = traverse (traverse init r) l
traverse init (Leaf x)   = x : init

cc tree = traverse [] (fmap2 h tree)

答案 1 :(得分:1)

这个有效

data Tree a = EmptyTree | Node a (Tree a) (Tree a)

treeToList :: (Ord a) => Tree a -> [a]   
treeToList EmptyTree = []         
treeToList (Node root left right) = treeToList left ++ [root] ++ treeToList right