如何清理级别遍历功能?

时间:2015-11-19 21:05:49

标签: haskell tree traversal

我正在处理一般定义的树设置,如下所示:

data Tree a = Node a [Tree a] deriving (Eq, Read, Show)

通过这个设置,我创建了一个函数,用于在树的特定级别打印节点(root为0级,root的直接子级为1级,等等)。这是功能:

level :: Int -> Tree a -> [a]
level 0 (Node a _) = [a]
level n (Node _ subtrees) = concatMap (level (n - 1)) subtrees

使用此函数作为基础,我创建了第二个函数levelorder,它以水平顺序遍历打印树中所有节点的列表。该功能目前看起来像这样:

levelorder :: Tree a -> [a]
levelorder tree = level 0 tree ++ level 1 tree ++ level 2 tree ++ level 3 tree

虽然这对我目前正在使用的树非常有用,但我想将它清理到适合任何大小的树的位置。如您所见,它目前仅适用于具有4级(0到3)的树。我将如何实现这一目标仍然可以将水平函数作为基础?

3 个答案:

答案 0 :(得分:3)

如果你有一个函数depth :: Tree a -> Int告诉你树有多深,那就像

一样简单
levelorder tree = concatMap (\lvl -> level lvl tree) [0..depth tree]

这不是一个特别快的实现,但是,你最终会多次遍历树。

答案 1 :(得分:1)

您可以成功遍历各个级别,直到节点用完为止:

levelorder :: Tree a -> [a]
levelorder t = concat $ takeWhile (not . null) $ map (`level` t) [0..]

答案 2 :(得分:0)

您首先需要深度函数,这样您就不需要修复连接的级别数。

depth :: Tree a -> Int
depth (Node _ [])       = 1
depth (Node _ r@(x:xs)) = 1 + maximum (map depth r)

然后,而不是修复使用(++)的次数, 您只需concat map从列表[0..depth tree]中提取的每个级别levelorder' tree = concatMap (flip level tree) [0..depth tree]级别函数的结果。

double operator()(double x, double y) // Remove the const. It's useless. { // Call the other overload using the member data. return (*this)(b, c, x, y); } double operator()(double bb, double cc, double x, double y) { // Not using any member data at all. return bb*cc*x*y; }