检查二叉树是否为二叉搜索树的函数?

时间:2016-10-04 14:41:13

标签: recursion boolean binary-tree binary-search-tree

我尝试编写以下方法来判断二叉树是否是二进制搜索树?我只通过了一半的测试用例。我做错了什么?

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;
}

2 个答案:

答案 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)))