检查一棵树是否是 BST
这是我检查一棵树是否是 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
更简洁的递归方法
您可以使用有界方法,即每个递归都有两个变量:
min
和max
。最初
min = INT_MIN
和max = 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)
withmin = node.val + 1
和max
保持不变。右子树的值应不小于
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
andmax
.Initially
min = INT_MIN
andmax = INT_MAX
if
node = NULL
then return True because an empty BST is a BSTelse check if
node.val < min or node.val > max
if this condition isTrue
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)
withmin
remaining the same andmax = node.val - 1
because the left subtrees should have values not greater thannode.val - 1
.The
max
cannot benode.val
because BST cannot have duplicate elements.Store the boolean return value in say
left
recurse for right :
recur(node.right)
withmin = node.val + 1
andmax
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
@Aditya 给出了更优雅的解决方案的成分。
通常不禁止二叉搜索树具有重复值,因此不应将“窗口”减少1。
以下是建议代码:
@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: