简体   繁体   English

N元树 - 是否对称

[英]N-ary trees - is it symmetric or not

Given an N-ary tree, find out if it is symmetric about the line drawn through the root node of the tree.给定一个 N 元树,找出它是否关于通过树的根节点绘制的线对称。 It is easy to do it in case of a binary tree.在二叉树的情况下很容易做到。 However for N-ary trees it seems to be difficult然而对于 N 叉树来说,这似乎很困难

One way to think about this problem is to notice that a tree is symmetric if it is its own reflection, where the reflection of a tree is defined recursively:考虑这个问题的一种方法是注意,如果一棵树是它自己的反射,那么它是对称的,其中树的反射是递归定义的:

  1. The reflection of the empty tree is itself.空树的倒影就是它本身。
  2. The reflection of a tree with root r and children c1, c2, ..., cn is the tree with root r and children reflect(cn), ..., reflect(c2), reflect(c1).具有根 r 和子节点 c1, c2, ..., cn 的树的反射是具有根 r 和子节点 reflect(cn), ..., reflect(c2), reflect(c1) 的树。

You can then solve this problem by computing the tree's reflection and checking if it's equal to the original tree.然后您可以通过计算树的反射并检查它是否等于原始树来解决这个问题。 This again can be done recursively:这再次可以递归完成:

  1. The empty tree is only equal to itself.空树只等于它自己。
  2. A tree with root r and children c1, c2, ..., cn is equal to another tree T iff the other tree is nonempty, has root r, has n children, and has children that are equal to c1, ..., cn in that order.具有根 r 和子节点 c1, c2, ..., cn 的树等于另一棵树 T 仅当另一棵树是非空的,具有根 r,有 n 个子节点,并且有等于 c1, ... 的子节点, cn 按照这个顺序。

Of course, this is a bit inefficient because it makes a full copy of the tree before doing the comparison.当然,这有点低效,因为它在进行比较之前制作了树的完整副本。 The memory usage is O(n + d), where n is the number of nodes in the tree (to hold the copy) and d is the height of the tree (to hold the stack frames in the recursion tom check for equality).内存使用量为 O(n + d),其中 n 是树中的节点数(用于保存副本),d 是树的高度(用于保存递归中的堆栈帧以检查是否相等)。 Since d = O(n), this uses O(n) memory.由于 d = O(n),这使用 O(n) 内存。 However, it runs in O(n) time since each phase visits each node exactly once.然而,它在 O(n) 时间内运行,因为每个阶段只访问每个节点一次。

A more space-efficient way of doing this would be to use the following recursive formulation:一种更节省空间的方法是使用以下递归公式:

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.

You can then define two trees to be mirrors as follows:然后,您可以将两棵树定义为镜像,如下所示:

  1. The empty tree is only a mirror of itself.空树只是它自己的一面镜子。
  2. A tree with root r and children c1, c2,..., cn is a mirror of a tree with root t and children d1, d2, ..., dn iff r = t, c1 is a mirror of dn, c2 is a mirror of dn-1, etc.具有根 r 和子节点 c1, c2,..., cn 的树是具有根 t 和子节点 d1, d2, ..., dn 的树的镜像,仅当 r = t, c1 是 dn 的镜像,c2 是dn-1等的镜子

This approach also runs in linear time, but doesn't make a full copy of the tree.这种方法也以线性时间运行,但不会制作树的完整副本。 Comsequently, the memory usage is only O(d), where d is the depth of the tree.因此,内存使用量仅为 O(d),其中 d 是树的深度。 This is at worst O(n) but is in all likelihood much better.这是最坏的 O(n),但很可能要好得多。

I would just do an in-order tree traversal( node left right) on the left sub-tree and save it to a list.我只会在左子树上进行有序树遍历(节点左右)并将其保存到列表中。 Then do another in-order tree traversal (node right left) on the right sub-tree and save it to a list.然后在右子树上进行另一个有序树遍历(节点右左)并将其保存到列表中。 Then, you can just compare the two lists.然后,您可以只比较这两个列表。 They should be the same.他们应该是一样的。

One more way to answer this question is to look at each level and see if each level is palindrome or not.回答这个问题的另一种方法是查看每个级别,看看每个级别是否是回文。 For Null nodes, we can keep adding dummy nodes with any value which is unique.对于空节点,我们可以继续添加具有任何唯一值的虚拟节点。

Take a stack Now each time start traversing through root node, now recursively call a function and push the element of left sub tree one by one at a particular level.取一个栈 现在每次开始遍历根节点,现在递归调用一个函数,将左子树的元素逐个压入特定层级。 maintain a global variable and update its value each time a left sub tree is pushed onto the stack.now call recursively(after recursive call to left sub tree)the right sub and pop on each correct match.doing this will ensure that it is being checked in symmetric manner.维护一个全局变量并在每次将左子树推入堆栈时更新其值。现在递归调用(在递归调用左子树之后)右子树并弹出每个正确匹配。这样做将确保它被以对称方式检查。

At the end if stack is empty ,ie all elements are processed and each element of stack has been popped out..you are through!最后如果堆栈为空,即所有元素都被处理并且堆栈的每个元素都已被弹出......你通过了!

It's not difficult.这并不难。 I'm going to play golf with this question.我要带着这个问题去打高尔夫球。 I got 7... anyone got better?我得了 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))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM