检查一棵树是否是 BST

发布于 2025-01-11 19:32:43 字数 2086 浏览 0 评论 0原文

这是我检查一棵树是否是 BST 的尝试:

public boolean isBST() {
    return isBSTRecursively(this.root, new Max());
}

class Max {
    int value;
}

private boolean isBSTRecursively(Node node, Max max) {
    if (node == null) return true; // to handle null root
  
    // to handle scenario when both child nodes are absent
    if(node.getLeft() == null && node.getRight() == null) {
        max.value = node.getValue();
        return true;
    }

    // if left child is absent, we only investigate right subtree
    if(node.getLeft() == null) {
        Max rightMax = new Max();
        boolean isRightBST = isBSTRecursively(node.getRight(), rightMax);
        max.value = Math.max(node.getValue(), rightMax.value);
        if(isRightBST && node.getValue() < rightMax.value) {
            return true;
        } else {
            return false;
        }
    } else {
        Max leftMax = new Max();
        boolean isLeftBST = isBSTRecursively(node.getLeft(), leftMax);
        // if right child is absent, we only investigate left subtree
        if(node.getRight() == null) {
            max.value = Math.max(node.getValue(), leftMax.value);
            if(isLeftBST && node.getValue() > leftMax.value) {
                return true;
            } else {
                return false;
            }
        } else {
            // we investigate both left and right subtrees
            Max rightMax = new Max();
            boolean isRightBST = isBSTRecursively(node.getRight(), rightMax);
            max.value = Math.max(Math.max(leftMax.value, node.getValue()), rightMax.value);
            if(isLeftBST && isRightBST && leftMax.value < node.getValue() && node.getValue() < rightMax.value) {
                return true;
            } else {
                return false;
            }
        }
    }

经多个测试用例测试,代码工作正常。

但我不确定这是否是一个好的、干净的方法。

递归方法看起来很大。我正在分别处理诸如左节点为空、右节点为空、节点本身为空、两个子节点为空等场景。我想它们都可以以更小、更干净的方式处理。

此外,我总是更倾向于迭代方法(我通常发现它更好地可视化)。在这里会更好吗(假设它可以迭代完成)?

有什么建议吗?

Here is my attempt to check whether a tree is a BST or not:

public boolean isBST() {
    return isBSTRecursively(this.root, new Max());
}

class Max {
    int value;
}

private boolean isBSTRecursively(Node node, Max max) {
    if (node == null) return true; // to handle null root
  
    // to handle scenario when both child nodes are absent
    if(node.getLeft() == null && node.getRight() == null) {
        max.value = node.getValue();
        return true;
    }

    // if left child is absent, we only investigate right subtree
    if(node.getLeft() == null) {
        Max rightMax = new Max();
        boolean isRightBST = isBSTRecursively(node.getRight(), rightMax);
        max.value = Math.max(node.getValue(), rightMax.value);
        if(isRightBST && node.getValue() < rightMax.value) {
            return true;
        } else {
            return false;
        }
    } else {
        Max leftMax = new Max();
        boolean isLeftBST = isBSTRecursively(node.getLeft(), leftMax);
        // if right child is absent, we only investigate left subtree
        if(node.getRight() == null) {
            max.value = Math.max(node.getValue(), leftMax.value);
            if(isLeftBST && node.getValue() > leftMax.value) {
                return true;
            } else {
                return false;
            }
        } else {
            // we investigate both left and right subtrees
            Max rightMax = new Max();
            boolean isRightBST = isBSTRecursively(node.getRight(), rightMax);
            max.value = Math.max(Math.max(leftMax.value, node.getValue()), rightMax.value);
            if(isLeftBST && isRightBST && leftMax.value < node.getValue() && node.getValue() < rightMax.value) {
                return true;
            } else {
                return false;
            }
        }
    }

Code works fine as tested with multiple test cases.

But I am not sure if this is a good, clean approach.

Recursive method is big it seems. I am dealing with scenarios like null left node, null right node, node itself null, both child nodes null etc. separately. I guess they all can be handled in a much smaller, and cleaner way.

Moreover, I am always more inclined towards iterative approach(I generally find it better to visualize). Would that be better here (given it can be done iteratively)?

Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一片旧的回忆 2025-01-18 19:32:43

更简洁的递归方法

您可以使用有界方法,即每个递归都有两个变量:minmax

  • 最初min = INT_MINmax = INT_MAX

  • if node = NULL then return True 因为空 BST 是 BST

  • 否则检查 node.val min 或 node.val > max 如果此条件为 True 则树不是 BST,返回 False 注意:严格不等式 >< 被使用,因为 BST 不允许重复元素。


  • 左递归:recur(node.left),其中 min 保持不变,并且 max = node.val - 1 因为左子树的值不应大于 node.val - 1

    max 不能是 node.val,因为 BST 不能有重复元素。
    将布尔返回值存储在 left

  • recurse for right 中:recur(node.right) with min = node.val + 1max 保持不变。

    右子树的值应不小于node.val + 1
    将布尔返回值存储在 right

  • return left && 中正确

A cleaner recursive approach

You could use a bounded approach, i.e. have two variables for every recursion: min and max.

  • Initially min = INT_MIN and max = INT_MAX

  • if node = NULL then return True because an empty BST is a BST

  • else check if node.val < min or node.val > max if this condition is True then tree is not a BST, return False Notice : the strict inequality > and < are used as BST doesn't allow duplicate elements.

  • recurse for left : recur(node.left) with min remaining the same and max = node.val - 1 because the left subtrees should have values not greater than node.val - 1.

    The max cannot be node.val because BST cannot have duplicate elements.
    Store the boolean return value in say left

  • recurse for right : recur(node.right) with min = node.val + 1 and max remaining the same.

    The right subtrees should have values not less than node.val + 1.
    Store the boolean return value in say right

  • return left && right

游魂 2025-01-18 19:32:43

@Aditya 给出了更优雅的解决方案的成分。

通常不禁止二叉搜索树具有重复值,因此不应将“窗口”减少1。

以下是建议代码:

public boolean isBST() {
    return isBSTRecursively(this.root, Integer.MIN_VALUE, Integer.MAX_VALUE);
}

private boolean isBSTRecursively(Node node, int min, int max) {
    return node == null
           || node.getValue() >= min && node.getValue() <= max
               && isBSTRecursively(node.getLeft(), min, node.getValue())
               && isBSTRecursively(node.getRight(), node.getValue(), max);           
}

@Aditya gave the ingredients of the more elegant solution.

It is generally not forbidden for a binary search tree to have duplicate values, so there should no be reduction of the "window" with 1.

Here is suggested code:

public boolean isBST() {
    return isBSTRecursively(this.root, Integer.MIN_VALUE, Integer.MAX_VALUE);
}

private boolean isBSTRecursively(Node node, int min, int max) {
    return node == null
           || node.getValue() >= min && node.getValue() <= max
               && isBSTRecursively(node.getLeft(), min, node.getValue())
               && isBSTRecursively(node.getRight(), node.getValue(), max);           
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文