如果一个巨大的二叉树并且不能放在内存中,你如何检查树是否是镜像。
我将此作为面试问题
答案 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;
}