【问题标题】:Why does this method cause an Infinite Recursive call?为什么此方法会导致无限递归调用?
【发布时间】:2013-04-02 10:20:23
【问题描述】:

我很难理解为什么这个类不起作用。这是数据结构课程作业的一部分(编辑:作业的截止日期已经过去,我只是想弄清楚......)。该节点是基于 BST 构建的 AVL 树的一部分,我选择实现它的方式是在我的 Node 类中创建方法来查找平衡因子和高度。

类的结构如下:

public class Node<T extends Comparable<? super T>> {

public T data;
public Node left;
public Node right;

public Node(T IN) {
    data = IN;
}

public Node(T IN, Node L, Node R) {
    this(IN);
    left = L;
    right = R;
}

@Override
public String toString() {
    return data.toString();
}

@Override
public Node clone() {
    return new Node(this.data) ;
}

public int getHeight() {
    return getHeight(this) ;
}

public int getBF() {

        //Calculate BF
        int balanceFactor = 0;
        if (right != null && left != null)
            balanceFactor = getHeight(right) - getHeight(left);
        else if (left != null) {
            balanceFactor = 0 - getHeight(left) ;
        }
        else if (right != null) {
            balanceFactor = getHeight(right) ;
        }
        else
            balanceFactor = 0 ;
        return balanceFactor ;
}

private int getHeight(Node p) {
    if (p.left == null && p.right == null ) {
        return 0 ;
    }
    else if (p.left != null && p.right != null) {
        return 1 + max(p.left.getHeight(), p.right.getHeight());
    }
    else if (p.left != null) {
        return 1 + p.left.getHeight() ;
    }
    else if (p.right != null) {
        return 1 + p.right.getHeight() ;
    }
    else {
        return 0;
    }
}

private int max(int x, int y) {
    if (x >= y) {
        return x;
    } else {
        return y;
    }
}

}

调用该方法的函数是:

@Override
public boolean insert(T el) {
    boolean test = super.insert(el) ;
    if (test) {
        return checkBalance(root) ;
    }
    else
        return false ;
}

我收到的例外是重复:

Exception in thread "main" java.lang.StackOverflowError
at Node.getHeight(Node.java:54)
at Node.getHeight(Node.java:33)
at Node.getHeight(Node.java:58)

【问题讨论】:

  • 顺便问一下,base case 不应该返回 1 而不是 0 吗?
  • 确保在默认和“int Node(T IN)”构造函数中左右引用null:)
  • 你检查过你的树上是否有一个圆圈吗?这可能会导致错误...
  • @Drewen:为什么不应该这样?
  • 嗯,在 C++ 中是“必须”的做法,但我刚刚在 Java 中看到它不是 :)

标签: java recursion stack-overflow avl-tree recursive-datastructures


【解决方案1】:

我建议你的树要么变形要么真的很大。代码似乎没有问题。

如果您的树以这样一种方式变形,以至于您在同一棵树中插入了两次 Node,那么此代码将中断。

添加 - 你吃的堆栈比你需要的多 - 用 getHeight(p.left) 等替换 p.left.getHeight() 等将避免每次递归推送一个堆栈。如果您的问题只是一棵大树,那么这可能会让您陷入困境,但这只会推迟问题。

【讨论】:

  • 如果我用一个简单的二叉树测试 getHeight() 和 getBF() 方法,它似乎可以工作,我会看看我的 AVL 树是否损坏,谢谢。
  • 我修好了!问题出在我的 AVL-tree 的 checkBalance() 方法中,我只是简单地切换了我的旋转,并且由于损坏的树而存在问题,所以感谢 @OldCurmudgeon 让我查看我的数据结构!
【解决方案2】:

通过查看这两种 getHeight 方法,您似乎没有树,而是有一个循环图。您应该从仅包含根的树开始测试,然后添加节点,直到观察到无限递归。您可能在重新平衡树的函数中有错误。

编辑:您应该将属性(至少左右)设为私有。

【讨论】:

  • 通过查看这两个 getHeight 方法,您似乎没有树而是循环图” - 您是如何得出这个结论的?
  • 因为如果它是一个非循环图,那么这些方法不会导致无限递归。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-02
  • 1970-01-01
  • 2012-09-04
  • 2020-12-28
  • 2014-03-18
  • 1970-01-01
相关资源
最近更新 更多