检查树是否是镜像?

时间:2012-04-04 18:59:08

标签: algorithm tree

如果一个巨大的二叉树并且不能放在内存中,你如何检查树是否是镜像。

我将此作为面试问题

3 个答案:

答案 0 :(得分:4)

如果树是另一棵树的镜像,一棵树的inorder遍历将与另一棵树相反。

所以只需在第一棵树上进行顺序遍历,在另一棵树上进行反向顺序遍历,并检查所有元素是否相同。

答案 1 :(得分:2)

我当然不能完全赞同这个答复;我的一些同事帮助了一些假设,并在我最初的想法中挖洞。非常感谢他们!

假设

  • 我们不能在内存中使用整个树,因此使用递归并不理想。让我们假设,为简单起见,我们在内存中最多只能容纳两个节点。

  • 我们知道 n ,即我们树中的关卡总数。

  • 我们可以对数据中的字符或行位置进行搜索。

  • 磁盘上的数据按深度排序。也就是说,磁盘上的第一个条目是root,接下来的两个是它的子节点,接下来的四个是它的子节点,依此类推。

  • 有些情况下数据是完美镜像的,而有些情况则不是。除非另有说明,否则与非空白数据交错的空白数据被视为“可接受”。

  • 只要可以比较值的等价性,我们就可以自由使用我们希望的任何数据类型。对象等价的测试可能并不理想,所以我们假设我们正在比较原语。

  • “镜像”表示在根的子节点之间镜像。为了使用不同的术语,祖父母的左孩子与其右孩子镜像,左孩子(父母)的左孩子与祖父母的右孩子的右孩子镜像。这在下图中说明;匹配的符号代表我们想要检查的镜像。

                G
          P*         P*
       C1&  C2^   C3^ C4&
    

方法

我们知道当我们从磁盘读取时我们应该期望每个级别有多少节点 - 2 k 的一些倍数。我们可以建立一个双循环来迭代树的总深度,以及每个级别中节点的计数。在此内部,我们可以简单地比较等值的最外层值,如果找到不相等的值则进行短路。

我们可以使用2 k 的倍数来确定每个外部位置的位置。任何级别的最左边的孩子总是2 k ,任何级别的最右边的孩子总是2 k + 1 -1。

小证明:第1级的最外层节点为2和3; 2 1 = 2,2 1 + 1 -1 = 2 2 -1 = 3.第2级的最外层节点为4和7; 2 2 = 4,2 2 + 1 -1 = 2 3 -1 = 7.可以将这一直扩展到第n个情况下。

的伪代码

int k, i;
for(k = 1; k < n; k++) { // Skip root, trivially mirrored
    for(i = 0; i < pow(2, k) / 2; i++) {
        if(node_retrieve(i + pow(2, k)) != node_retrieve(pow(2, (k+1)-i)) {
            return false;
        }
     }
 }
 return true;

思想

这类问题是一个很好的面试问题,因为他们很可能希望看到你如何解决这个问题。这种方法可能很糟糕,可能是完美无暇的,但是雇主会希望你花时间,在纸上或白板上画东西,并向他们询问有关如何存储数据,如何阅读,以及对寻求等的限制等。

这不是采访者感兴趣的编码方面,而是问题解决方面。

答案 2 :(得分:0)

递归很容易。

struct node {
        struct node *left;
        struct node *right;
        int payload;
        };

int is_not_mirror(struct node *one, struct node *two)
{
if (!one && !two) return 0;
if (!one) return 1;
if (!two) return 1;
if (compare(one->payload, two->payload)) return 1;
if (is_not_mirror(one->left, two->right)) return 1;
if (is_not_mirror(one->right, two->left)) return 1;
return 0;
}