如何在Java中正确清除整个二叉树?

时间:2014-03-08 15:22:29

标签: java binary-tree

我有简单的二叉搜索树类,其实例变量类型为Node,它是根。这并不复杂,只是您之前看到的与Node类相同的基本BST类,其中包含数据类型的字段和对左右节点的两个引用。我想要一个清除树的方法。最初,我想,好吧,这是:

void clearTree() { root = null; }

但是我的教授声称这并没有真正从内存中清除树,因为仍然有来自树中父节点的节点的引用......即使我们没有对它们的引用。这样说是对的吗?如果是,为什么这不能从记忆中清除树?我以为一旦我们失去对它的引用,它就会被垃圾收集。

3 个答案:

答案 0 :(得分:3)

您无法再访问的任何内容(通过代码中的任何引用/指针)都有资格进行垃圾回收。

因此,假设您没有保留对除根节点引用之外的任何其他节点的任何引用,那么在您将根引用置空时,整个树都将启动GC。

如果你真的想向你的教授证明这一点,我建议你得到eclipse memory analyzer的副本,在将字段归零后立即拍摄快照(使用与jdk捆绑在一起的hprof命令行实用程序,让你的代码睡20秒,这样很容易捕获)然后你可以证明内存中没有强可达的节点

答案 1 :(得分:3)

你的教授是正确的,使root等于null将不会释放整个树。在像C这样的语言中,如果你使root=null整个树仍在内存中。

但是在Java中,正如@radai所说,一旦你没有对树节点的更多引用,垃圾收集器就会为你清理它。因此,在Java上下文中,make root=null将起作用。

无论如何,如果你确实需要清理树的每个单个节点(例如,C / C ++语言中需要什么),你可以使用pos-order算法。当然,您需要使算法适应您的变量名称和结构(或类,如果您想在Java中应用它)。

void clearTree(treenode *node) {
    if (node != NULL) {
        clearTree( node->leftChild );
        clearTree( node->rightChild );
        delete( node ); // Or in Java, node = null;
    }
}

答案 2 :(得分:0)

我认为你的教授可能错了。考虑一个复合对象A

class A {
   private B b;
   private C c;

   public A(B b, C c){
     this.b = b;
     this.c = c;
   }

}

我们将其用作:

A a = new A(new B(), new C());

当你这样做时:

a = null;

a引用的对象将被垃圾收集,并与对象的任何其他部分一起使用(如果它们未在其他地方引用)。这种情况一直在发生,我们甚至都没想过。

我相信这棵树也是一样的。它将以递归方式声称其他对象无法到达。如果没有其他对该根的引用。

修改

显示GC如何判断对象是否可访问的gif:here