镜像一棵树

时间:2011-12-24 12:33:13

标签: haskell

分配是镜像一棵树(所以在每个级别,最左边的孩子都是最右边的等等。)

数据结构:

import Data.List

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

到目前为止我的目标:

mirror :: Rose a -> Rose a
mirror (Node x []) = Node x []
mirror (Node x (y:ys)) = mirror (myReverse y)

--reverses given node children
myReverse :: Rose a -> Rose a
myReverse (Node x y) = Node x (reverse y)

所以当我用例子运行这段代码时:

Main> mirror (Node 1 [Node 11 [Node 111 [], Node 112[]], Node 12 [Node 121[]]])

该函数返回Node 112 [],意味着它卡在最左边的叶子上。从我的代码判断它似乎是合乎逻辑的,因为我没有在y:ys传递给定节点子节点的尾部。不知何故,我必须能够反转给定节点的第一个孩子的所有孩子传递尾部以获得相同的功能。无论我怎么努力,我都无法做到这一点,看起来我已达到了逻辑思维的极限。

Documentation for reverse function

2 个答案:

答案 0 :(得分:5)

我会避免像第一个孩子和其他孩子那样小问题。相反,试着看看整个画面。

                a                             a
             /     \                       /     \
            b       c        ===>         c       b
          / | \    / \                   / \    / | \
         d  e  f   g  h                 h   g  f  e  d

如果我们以递归的方式考虑这个问题,我们可以观察到我们可以通过以下方式镜像树:

  1. 扭转孩子们的秩序。
  2. 递归镜像孩子们自己。
  3. 您已经知道如何使用reverse。要将函数f应用于列表中的每个元素,您可以使用map f。试着看看你是否可以一起使用它们来解决它。

    <强>扰流:

      

    mirror (Node a children) = Node a (reverse $ map mirror children)

答案 1 :(得分:3)

正如您正确指出的那样,您在ys函数中根本没有使用mirror,因此结果可能不正确。

要解决这个问题,有必要考虑Rose的递归结构,以及镜像如何影响它。

即,为了镜像树,你必须保持它的根,并(递归地)镜像它的每个子节点,同时颠倒所述子节点的顺序。

如果这很清楚,那么只需将这些单词翻译成Haskell代码即可。

问问自己:

  1. 如何将功能应用于每个孩子并将结果收集到列表中?

  2. 如何以相反的顺序执行1?

  3. 我是否真的需要单独处理空列表案例?