我正在开发一个涉及平衡二叉树的项目,我遇到了一些问题。
对于我项目的一部分,我想查看树(或子树)并比较所述子树的子路径和右子路径的最大长度。如果这些路径的最大长度之间的绝对差值大于1,我想返回找到具有此属性的第一个节点。逻辑有点简单..例如,如果我有树:
我的算法将查看64并比较沿左右两侧的路径长度(分别为5和4)。这不会创建一个标志,因为差异为1.然后我会递归地查看64的孩子。首先它会看到43,然后转到26. 26之后(因为它的每个子节点的长度都是1),算法将移动到62.此时会抛出一个标志,因为62s左边的路径有一个长度3,它没有正确的道路。这是我想退出循环并返回62的地方。但是,我的循环继续运行,直到它检查最终节点。
如您所见,算法继续运行并返回一个空节点而不是我想要的节点。我不确定为什么会这样做,但我认为它与优先级和范围有关。特定算法的代码如下:
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语句被执行。但是,这并没有像我假设的那样退出函数。
答案 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),你就会立即知道返回值。