返回语句无法从循环中正常工作

时间:2017-10-07 00:34:10

标签: java recursion scope

我正在开发一个涉及平衡二叉树的项目,我遇到了一些问题。

对于我项目的一部分,我想查看树(或子树)并比较所述子树的子路径和右子路径的最大长度。如果这些路径的最大长度之间的绝对差值大于1,我想返回找到具有此属性的第一个节点。逻辑有点简单..例如,如果我有树: enter image description here

我的算法将查看64并比较沿左右两侧的路径长度(分别为5和4)。这不会创建一个标志,因为差异为1.然后我会递归地查看64的孩子。首先它会看到43,然后转到26. 26之后(因为它的每个子节点的长度都是1),算法将移动到62.此时会抛出一个标志,因为62s左边的路径有一个长度3,它没有正确的道路。这是我想退出循环并返回62的地方。但是,我的循环继续运行,直到它检查最终节点。 enter image description here

enter image description here

如您所见,算法继续运行并返回一个空节点而不是我想要的节点。我不确定为什么会这样做,但我认为它与优先级和范围有关。特定算法的代码如下:

    public BinaryNode<Integer> NodeCheck(BinaryNode<Integer> Node) throws IllegalStateException
    {
        System.out.println("CHECKING NODE: " + Node.getData());

        int leftHeight = 0;
        int rightHeight = 0;

        if (Node.hasLeft())
        {
            leftHeight = 1 + findHeight(Node.getLeft());
        }

        if (Node.hasRight())
        {
            rightHeight = 1 + findHeight(Node.getRight());
        }
        System.out.println("LEFT HEIGHT = " + leftHeight);
        System.out.println("RIGHT HEIGHT = " + rightHeight);

        int z = Math.abs(leftHeight - rightHeight);
        if (z > 1)
        {
            System.out.println();
            System.out.println();
            System.out.println("PROBLEM DETECTED AT NODE " + Node.getData() + " ATTEMPTING TO RETURN NODE");
            BinaryNode<Integer> flag = createNode(Node.getData(), Node.getParent(),Node.getLeft(), Node.getRight());

            return flag;
        }

        for (BinaryNode<Integer> c : children(Node))
            {
                if (findHeight(c) > 1 && z<= 1)
                    {NodeCheck(c);}
            }


        return createNode(0,null,null,null);

    }

我认为重要的是要注意我最终在if(z&gt; 1)语句中处理信息,因为执行了System.out.println()语句,这使我相信return语句被执行。但是,这并没有像我假设的那样退出函数。

2 个答案:

答案 0 :(得分:2)

问题是,你以递归方式调用此方法,但没有检查。

您应该更改以下内容以使其正常工作:

  • 最终return应该返回null
  • 在此之前的循环中,您应该检查返回的值,如果不是null则返回它。

所以你方法的最后一部分应该是这样的:

    for ( final BinaryNode<Integer> c : children( node ) )
    {
        if ( findHeight( c ) > 1 && z <= 1 )
        {
            final BinaryNode<Integer> res = nodeCheck( c );
            if ( null != res )
                return res;
        }
    }
    return null;
}

运行它会产生此输出:

CHECKING NODE: 64
LEFT HEIGHT = 5
RIGHT HEIGHT = 4
CHECKING NODE: 43
LEFT HEIGHT = 3
RIGHT HEIGHT = 4
CHECKING NODE: 26
LEFT HEIGHT = 2
RIGHT HEIGHT = 2
CHECKING NODE: 62
LEFT HEIGHT = 3
RIGHT HEIGHT = 0


PROBLEM DETECTED AT NODE 62 ATTEMPTING TO RETURN NODE

答案 1 :(得分:1)

我认为你的问题来自你在for循环中调用persondiv data-gender == memberslist data-gender persondiv data-age between memberslist data-agestart and data-ageend persondiv data-grade(number) between memberslist data-gradestart and data-gradeend 的地方。我假设当您说NodeCheck()时,您打算说 if (findHeight(c) > 1 && z <=1)

然而,当你第一次(在根上)运行它时,如果在那一点z <= 1(它在你给出的例子中),它将调用{{1}关于那个根的孩子(即43和92)。所以即使它找到一个z> 1的节点在左边1,同样的检查已经向右请求,这就是为什么当左边返回时它不会停止。

这里有一个替代循环的方法:你可以单向下去等待,看看是否有任何东西沿着那条路走下去,然后再走另一条路。 您的代码变为

"if the child node has a height greater than 1 and 'z' has not yet been found to be greater than 1, then check the said child node"

请注意,当您向孩子致电NodeCheck()时,您不需要检查public BinaryNode<Integer> NodeCheck(BinaryNode<Integer> Node) throws IllegalStateException { System.out.println("CHECKING NODE: " + Node.getData()); int leftHeight = 0; int rightHeight = 0; if (Node.hasLeft()) { leftHeight = 1 + findHeight(Node.getLeft()); } if (Node.hasRight()) { rightHeight = 1 + findHeight(Node.getRight()); } System.out.println("LEFT HEIGHT = " + leftHeight); System.out.println("RIGHT HEIGHT = " + rightHeight); int z = Math.abs(leftHeight - rightHeight); if (z > 1) { System.out.println(); System.out.println(); System.out.println("PROBLEM DETECTED AT NODE " + Node.getData() + " ATTEMPTING TO RETURN NODE"); BinaryNode<Integer> flag = createNode(Node.getData(), Node.getParent(),Node.getLeft(), Node.getRight()); return flag; } /*EDIT STARTS HERE*/ if (Node.hasLeft() && findHeight(Node.getLeft()) > 1) //Check in the left node and see if it returns a flag { BinaryNode<Integer> left = Node.getLeft(); BinaryNode<Integer> result = CheckNode(left); //If 'result' is null, then there was no flag, otherwise it found a flag. So check for that if (result != null) //If this condition is met, then result is a flag and the left child //found a z > 1. So cut the operations here and just return the same //flag to the one who called 'CheckNode()' on this 'Node'. {return result;} } if (Node.hasRight() && findHeight(Node.getRight()) > 1) //Check in the right node and see if it returns a flag { BinaryNode<Integer> right = Node.getRight(); BinaryNode<Integer> result = CheckNode(right); //Same as above if (result != null) //If this condition is met, then result is a flag and the right //child found a z > 1. So cut the operations here and just return //the same flag to the one who called 'CheckNode()' on this 'Node'. {return result;} } /*EDIT ENDS HERE*/ return null; } ,因为如果z大于1,则会返回并退出检查标志并执行CheckNode()

最后返回z <= 1看起来更容易,所以如果它找到一个标志(将是一个BindaryNode对象)或者不是(将为null),你就会立即知道返回值。