我尝试编写以下方法来判断二叉树是否是二进制搜索树?我只通过了一半的测试用例。我做错了什么?
boolean checkBST(Node root) {
boolean leftflag = false;
boolean rightflag = false;
Node l = root.left;
Node r = root.right;
if(l!=null) {
if(root.data <= l.data) {
leftflag = false;
}
else {
leftflag = true;
checkBST(l);
}
}
if(leftflag == false)
return false;
if(r != null) {
if(root.data >= r.data) {
rightflag = false;
}
else {
rightflag = true;
checkBST(r);
}
}
if(rightflag == false)
return false;
return true;
}
答案 0 :(得分:0)
我可以看到一个案例,你的程序可能会错误地返回错误。
想象一下,你有一棵树有3个分支,如下:
7
/ \
3 8
\ / \
4 6 9
你的程序从7(root)开始,在false(leftflag和rightflag)创建两个boolean,检查left是否为null。事实并非如此。然后它检查左边的数据&lt; =右边的数据。它是。
所以你递归调用你的函数,左边有一个新的根节点(例子中为3)。同样,它在false初始值处创建两个布尔值,检查左节点是否为空。它是 !所以它会跳过整个,如果在返回之前直接转到你的另一个。
// The condition here is respected, there is no left node
// But the tree is an actual search tree, you didn't check right node
// Before returning false.
if(leftflag == false)
return false
我要做的是
if(l != null)
{
if(root.data<=l.data)
{
return false;
}
else
{
// recursive call here
}
}
if(r != null)
{
// Same as left node here
}
因此,即使您的左侧节点为空,程序仍会检查正确的节点。希望我帮助了一点!
答案 1 :(得分:0)
您的主要错误是忽略了递归调用的返回值。例如:
else {
leftflag = true;
checkBST(l);
}
}
if(leftflag == false)
return false;
如果checkBST(l)返回false,则忽略它。你永远不会保存价值。因此,您对leftflag的后续检查完全不了解子树的适用性。在语义上,您的例程假定所有子树都是BST - 您设置标志,在子树上重复,但不要更改标志。试试这个逻辑:
else
leftflag = checkBST(l)
现在,请熟悉布尔表达式。例如,针对布尔常量测试布尔值有点浪费。而不是
if (flag == false)
直接检查:
if (!flag)
在大多数语言中检查指针是否为null:
if (l)
最后,如果你只想将它们设置为与第一个动作相同的值,则不要初始化你的标志。
现在,您的代码可能如下所示:
boolean leftflag = false;
boolean rightflag = false;
if(l) {
if(root.data > l.data) {
leftflag = checkBST(l);
}
}
if(!leftflag)
return false;
if(r) {
if(root.data < r.data) {
rightflag = checkBST(r);
}
}
if(rightflag == false)
return false;
return true;
}
现在跟随逻辑流程更容易一些。请注意,您的基本情况基本失败:空树 平衡,但您返回 false 。
现在,如果您想了解有关逻辑短路和布尔表达式的更多信息,您可以将常规减少到更像这样的程序:
return
(!root.left || // Is left subtree a BST?
(root.data > root.left.data &&
checkBST(root.left)))
&&
(!root.right || // Is right subtree a BST?
(root.data > root.right.data &&
checkBST(root.right)))