N-ary树 - 是对称的还是不对称的

时间:2010-02-23 04:29:18

标签: algorithm data-structures tree

给定N-ary树,找出它是否与通过树的根节点绘制的线对称。在二叉树的情况下很容易做到这一点。然而对于N-ary树来说似乎很难

5 个答案:

答案 0 :(得分:6)

考虑这个问题的一种方法是注意树是对称的,如果它是自己的反射,树的反射是递归定义的:

  1. 空树的倒影本身就是。
  2. 具有根r和子c1,c2,...,cn的树的反射是具有根r的树,并且子反射(cn),...,反射(c2),反射(c1)。< / LI>

    然后,您可以通过计算树的反射并检查它是否等于原始树来解决此问题。这也可以递归地完成:

    1. 空树只等于它自己。
    2. 具有根r和子c1,c2,...,cn的树等于另一棵树T如果另一棵树是非空的,具有根r,有n个子节点,并且具有等于c1的子节点,。 ..,cn按此顺序。
    3. 当然,这样做效率有点低,因为它在进行比较之前会生成树的完整副本。内存使用量为O(n + d),其中n是树中的节点数(用于保存副本),d是树的高度(用于保持递归中的堆栈帧检查是否相等)。由于d = O(n),因此使用O(n)存储器。但是,它在O(n)时间内运行,因为每个阶段只访问每个节点一次。

      更节省空间的方法是使用以下递归公式:

      1. The empty tree is symmetric.
      2. A tree with n children is symmetric if the first and last children are mirrors, the second and penultimate children are mirrors, etc.
      

      然后,您可以将两个树定义为镜像,如下所示:

      1. 空树只是自己的一面镜子。
      2. 具有根r和子c1,c2,...,cn的树是具有根t的子树的镜像,并且子节点d1,d2,...,dn iff r = t,c1是dn的镜像,c2是dn-1等的镜像。
      3. 此方法也以线性时间运行,但不会生成树的完整副本。因此,内存使用仅为O(d),其中d是树的深度。这是最糟糕的O(n),但很可能更好。

答案 1 :(得分:2)

我只是在左子树上进行有序树遍历(节点左右)并将其保存到列表中。然后在右子树上执行另一个有序树遍历(节点右侧)并将其保存到列表中。然后,您可以只比较两个列表。它们应该是一样的。

答案 2 :(得分:0)

这并不困难。我打算用这个问题打高尔夫球。我有7个......有人变得更好了吗?

data Tree = Tree [Tree]
symmetrical (Tree ts) =
    (even n || symmetrical (ts !! m)) &&
    all mirror (zip (take m ts) (reverse $ drop (n - m) ts))
    where { n = length ts; m = n `div` 2 }
mirror (Tree xs, Tree ys) =
    length xs == length ys && all mirror (zip xs (reverse ys))

答案 3 :(得分:0)

筹码 现在每次开始遍历根节点, 现在递归调用一个函数,并在特定级别逐个推送左子树的元素。 每次将左子树推入堆栈时,都会维护一个全局变量并更新其值。现在以递归方式(在递归调用左子树之后)调用右子并弹出每个正确的匹配。这将确保它正在以对称的方式检查。

最后如果堆栈是空的,即所有元素都被处理掉了,堆栈的每个元素都被弹出了......你完成了!

答案 4 :(得分:0)

回答这个问题的另一种方法是查看每个级别,看看每个级别是否是回文。对于Null节点,我们可以继续添加具有唯一值的虚拟节点。