C# 如何确定二叉树是否为BST
我试图找出一个逻辑来确定二叉树是否是BST。我想使用索引方法,我不想使用额外的数组来存储所有传入的值,因为我们知道索引应该按顺序排序。我想检查传入值,而不必将其存储在数组中。下面是我的尝试,但不起作用C# 如何确定二叉树是否为BST,c#,data-structures,tree,binary-tree,binary-search-tree,C#,Data Structures,Tree,Binary Tree,Binary Search Tree,我试图找出一个逻辑来确定二叉树是否是BST。我想使用索引方法,我不想使用额外的数组来存储所有传入的值,因为我们知道索引应该按顺序排序。我想检查传入值,而不必将其存储在数组中。下面是我的尝试,但不起作用 public bool CheckBST(BstNode root) { BstNode prev = new BstNode(Int32.MinValue); if (root == null)
public bool CheckBST(BstNode root)
{
BstNode prev = new BstNode(Int32.MinValue);
if (root == null)
return true;
if (root.left != null)
{
return CheckBST(root.left);
}
if (prev != null && prev.data >= root.data) // means data is not sorted hence NOT BST
return false;
prev = root;
if(root.right!=null)
{
return CheckBST(root.right);
}
return true;
}
因此,通常在BST中,每个节点中有三件事。这就是数据和左右两个指针。如果任何节点中有两个以上的可用指针,则该节点不是BST。最好在节点级别确定该节点中的指针是否多于应有的数量。搜索树会浪费时间和资源
下面是一个很好的方法,你不需要prev
当然,在需要的地方检查空值。您不能每次在
CheckBST
中初始化prev
。您可以将prev
设置为全局。我还将prev
设置为类型integer
int prev = Int32.MinValue; //made this global and integer type
public bool CheckBST(BstNode root) {
if (root == null)
return true;
bool isLeftBST = CheckBST(root.left);
if (isLeftBST == false) return false;
if (prev != Int32.MinValue && prev >= root.data) // means data is not sorted hence NOT BST
return false;
prev = root.data; //mark the prev before traversing the right subtree
return isLeftBST && CheckBST(root.right);
}
忽略语法问题(如果有)。我尝试了更多的伪代码
当然,还有其他方法可以解决这个问题。类似于跟踪到目前为止的最小值和最大值(在@user1672994-answer中)。给定一个二叉树,下面确定它是否是有效的二叉搜索树(BST)
- 节点的左子树仅包含键小于的节点 节点的密钥
- 节点的右子树仅包含键更大的节点 而不是节点的键
- 左子树和右子树也必须是二进制搜索树
public class TreeNode
{
public int Val { get; set; }
public TreeNode Left { get; set; }
public TreeNode Right { get; set; }
public TreeNode(int x) { this.Val = x; }
}
检查验证的代码是
public bool IsValidBST(TreeNode root)
{
return IsValidBST(root, int.MinValue, int.MaxValue);
}
private bool IsValidBST(TreeNode root, int minValue, int maxValue)
{
if (root == null)
{
return true;
}
int nodeValue = root.Val;
if (nodeValue < minValue || nodeValue > maxValue)
{
return false;
}
return IsValidBST(root.Left, minValue, nodeValue - 1) && IsValidBST(root.Right, nodeValue + 1, maxValue);
}
如果您可以使
CheckBST
返回所检查的BST的范围(最小值、最大值),则应使用以下递归函数:
// Defines the return value that represents BST check failure.
const pair<int, int> kCheckFailed(Int32.MaxValue, Int32.MinValue);
pair<int, int> CheckBST(const BstNode& curr)
{
pair<int, int> left_ret(curr.value, curr.value);
pair<int, int> right_ret(curr.value, curr.value);
// Makes sure the left subtree, if any, is a BST, and its max
// (`left_ret.second`) is no greater than `curr.value`
if (curr.left) {
left_ret = CheckBST(*curr.left);
if (left_ret == kCheckFailed || left_ret.second > curr.value)
return kCheckFailed;
}
// Makes sure the right subtree, if any, is a BST, and its min
// (`right_ret.first`) is not less than `curr.value`.
if (curr.right) {
right_ret = CheckBST(*curr.right);
if (right_ret == kCheckFailed || right_ret.first < curr.value)
return kCheckFailed;
}
// Returns range by combining min of left subtree and max of right subtree.
return make_pair(left_ret.first, right_ret.second);
}
//定义表示BST检查失败的返回值。
常量对kCheckFailed(Int32.MaxValue,Int32.MinValue);
对检查BST(常量BST节点和当前)
{
对左箭头(当前值、当前值);
对右箭头(当前值、当前值);
//确保左子树(如果有)是BST及其最大值
//(`left_ret.second`)不大于`curr.value`
如果(当前左侧){
left_-ret=CheckBST(*当前左侧);
if(left_ret==kCheckFailed | | left_ret.second>当前值)
返回kCheckFailed;
}
//确保正确的子树(如果有)是BST及其最小值
//(`right_ret.first`)不小于`curr.value`。
如果(当前右侧){
右侧=检查BST(*当前右侧);
如果(右返回==kCheckFailed | |右返回第一次<当前值)
返回kCheckFailed;
}
//通过组合左子树的最小值和右子树的最大值返回范围。
返回make_对(左后第一,右后第二);
}
请注意,CheckBST
通过引用获取(子)树根,以确保节点(curr
)始终有效。但是,curr.left
或curr.right
可能仍然为空,在这种情况下,相应的最小值或最大值分别为curr.value
,初始化为ret_left
和ret_right
- 递归,时间复杂度为O(1)
- 删除注释行以查看如何调用它
- 对于第一个调用过程
isBST(root,null,null)
public bool isBST(节点根、节点l、节点r) { //WriteLine($“处理:isBST({root?.data},{l?.data},{r?.data})”); if(root==null)返回true; 如果(l!=null&&root.data=r.data)返回false; //Console.WriteLine($“isBST({root?.left?.data},{l},{root?.data})和&isBST({root?.right?.data},{root?.data},{r?.data})”; 返回isBST(root.left,l,root)和&isBST(root.right,root,r); }
// Defines the return value that represents BST check failure.
const pair<int, int> kCheckFailed(Int32.MaxValue, Int32.MinValue);
pair<int, int> CheckBST(const BstNode& curr)
{
pair<int, int> left_ret(curr.value, curr.value);
pair<int, int> right_ret(curr.value, curr.value);
// Makes sure the left subtree, if any, is a BST, and its max
// (`left_ret.second`) is no greater than `curr.value`
if (curr.left) {
left_ret = CheckBST(*curr.left);
if (left_ret == kCheckFailed || left_ret.second > curr.value)
return kCheckFailed;
}
// Makes sure the right subtree, if any, is a BST, and its min
// (`right_ret.first`) is not less than `curr.value`.
if (curr.right) {
right_ret = CheckBST(*curr.right);
if (right_ret == kCheckFailed || right_ret.first < curr.value)
return kCheckFailed;
}
// Returns range by combining min of left subtree and max of right subtree.
return make_pair(left_ret.first, right_ret.second);
}
public bool isBST(Node root, Node l, Node r)
{
// Console.WriteLine($"Processing: isBST({root?.data}, {l?.data}, {r?.data})");
if (root == null) return true;
if (l != null && root.data <= l.data) return false;
if (r != null && root.data >= r.data) return false;
// Console.WriteLine($"isBST({root?.left?.data}, {l}, {root?.data}) && isBST({root?.right?.data}, {root?.data}, {r?.data})");
return isBST(root.left, l, root) && isBST(root.right, root, r);
}