通过递归

时间:2015-07-21 06:07:25

标签: java recursion binary-search-tree

问题是我需要编写一个函数来验证二叉树是否是一个有效的二叉搜索树

这是我的代码:

public static boolean betterValidBSTArray(TreeNode node) {
    WrapInt lastData = null;
    return validate(lastData, node);
}

private static boolean validate(WrapInt lastData, TreeNode node) {
    if(node == null) return true;
    if(!validate(lastData, node.getLeft())) return false;
    if(lastData != null && node.getData() <= lastData.value) return false;
    if(lastData == null) lastData = new WrapInt();
    lastData.value = node.getData();
    if(!validate(lastData, node.getRight())) return false;

    return true;
}

class WrapInt { int value; }

问题是,这个算法不起作用。我给出了一些断点,并指出对于每个堆栈调用,在堆栈调用完成后lastData被赋值给一个值后,前一个堆栈调用将继续lastData = null,即使lastData也有前一个堆栈调用的实际值。 / p>

感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

要修复代码,不应该执行if(lastData == null) lastData = new WrapInt();,因为它只将新对象的引用分配给方法调用参数,该参数是每个堆栈调用的局部变量,并且不应传递null作为lastData,但是将在整个递归中使用的对象,仅更改其value

答案 1 :(得分:2)

你在引用工作的方式上做出了错误的假设。

public static boolean betterValidBSTArray(TreeNode node){        WrapInt lastData = null;        return validate(lastData,node);    }

您似乎认为这会将lastData的地址传递给validate,并在触发正确的条件时将其设置为对象。

但真正做的是:

   return validate(null, node);

因为lastData = null的值。

您必须传递底层方法要填充的对象,因为引用始终按值传递。 (所以你传递值null,而不是像你在c ++中那样传递lastData变量的地址)。

有关更好的说明,请参阅the answers here

解决方案是在外部创建引用,然后将其传递给您使用的方法。

public static boolean betterValidBSTArray(TreeNode node) {
     WrapInt lastData = new WrapInt();
     return validate(lastData, node);
} 

如果你想要区分null / not null(如果这在你的代码中有意义,例如找到它),你可以使用

class WrapInt {
    Integer value;
}

class WrapInt {
    private int value;
    private boolean set;
    public boolean wasSet() { return set; }
    public int getValue() { return value; } 
    public void setValue(int value) { this.value = value; set = true; }
}

这样递归之外的代码就可以访问这个状态信息。

答案 2 :(得分:0)

您需要在betterValidBSTArray中创建WrapInt()对象,并为其值赋值null。这样你就可以传递lastData引用了。试试这个,它会起作用。