是具有递归的有效通用二叉搜索树

Is Valid Generic Binary Search Tree with Recursion

为了检查二叉搜索树的有效性,我使用了一种方法。但是在针对有效的 二进制搜索树 .

进行测试时,该方法总是 returns false

Online Demo Here

代码

public class Program
{
    public static void Main()
    {
        BinarySearchTree<int> tree = new BinarySearchTree<int>();
        tree.Insert(2);
        tree.Insert(1);
        tree.Insert(3);
        Console.WriteLine(tree.IsValidBinarySearchTreeRecursive(tree.root).ToString()); // this is supposed to return true when tested against the simple tree above
    }
}

public class Node<T> where T : IComparable
{
    public Node<T> left;
    public Node<T> right;
    public T data;

    public Node(T data)
    {
        this.left = null;
        this.right = null;
        this.data = data;
    }
}

public class BinarySearchTree<T> where T : IComparable
{
    public Node<T> root;

    public BinarySearchTree()
    {
        this.root = null;
    }

    public bool Insert(T data)
    {
        Node<T> before = null;
        Node<T> after = this.root;

        while(after != null)
        {
            before = after;

            if(data.CompareTo(after.data) < 0)
                after = after.left;
            else if(data.CompareTo(after.data) > 0)
                after = after.right;
            else
                return false;
        }

        Node<T> newNode = new Node<T>(data);

        if (this.root == null)
        {
            this.root = newNode;
        }
        else
        {
            if(data.CompareTo(before.data) < 0)
                before.left = newNode;
            else
                before.right = newNode;
        }

        return true;
    }

    private bool _HelperForIsValidBinarySearchTreeRecursive(Node<T> node, T lower, T upper)
    {
        if (node == null)
            return true;

        T val = node.data;

        Type nodeType = typeof(T);

        if(nodeType.IsNumeric())
        {
            if(val.CompareTo(lower) <= 0)
                return false;
            if(val.CompareTo(upper) >= 0)
                return false;
        }
        else
        {
            if(lower != null && val.CompareTo(lower) <= 0)
                return false;
            if(upper != null && val.CompareTo(upper) >= 0)
                return false;
        }

        if(!_HelperForIsValidBinarySearchTreeRecursive(node.right, val, upper))
            return false;
        if(!_HelperForIsValidBinarySearchTreeRecursive(node.left, lower, val))
            return false;

        return true;
    }
    public bool IsValidBinarySearchTreeRecursive(Node<T> root)
    {
        Type nodeType = typeof(T);

        if(nodeType.IsNumeric())
            return _HelperForIsValidBinarySearchTreeRecursive(root, root.data, root.data);

        return _HelperForIsValidBinarySearchTreeRecursive(root, default(T), default(T));
    }
}

public static class StaticUtilities
{
    private static readonly HashSet<Type> NumericTypes = new HashSet<Type>
    {
        typeof(int),  typeof(double),  typeof(decimal),
        typeof(long), typeof(short),   typeof(sbyte),
        typeof(byte), typeof(ulong),   typeof(ushort),  
        typeof(uint), typeof(float)
    };
    public static bool IsNumeric(this Type myType)
    {
        return NumericTypes.Contains(Nullable.GetUnderlyingType(myType) ?? myType);
    }
}

你的问题在这里:

if(val.CompareTo(lower) <= 0)
  return false; // you are always hitting this line
if(val.CompareTo(upper) >= 0)
  return false;

因为你的 T val = node.data; 和你的下半身甚至你的上半身都是 node.data 来自你的第一个电话。

所以很可能要修复的行是

return _HelperForIsValidBinarySearchTreeRecursive(root, root.data, root.data);

我猜你的本意是用根比较左右吧?

基于此:https://www.geeksforgeeks.org/a-program-to-check-if-a-binary-tree-is-bst-or-not/

对于您的数字方法,您的解决方案应该是:

/* false if this node violates the min/max constraints */
if (node.data < min || node.data > max) 
{ 
    return false; 
} 

所以你的代码变成:

if(val.CompareTo(lower) < 0)
  return false; // you are always hitting this line
if(val.CompareTo(upper) > 0)
  return false;

然后你将遇到下一个障碍。我对解决方案的建议是改变这个:

private bool _HelperForIsValidBinarySearchTreeRecursive(Node<T> node, T lower, T upper)

private bool _HelperForIsValidBinarySearchTreeRecursive(Node<T> node, Node<T> leftNode<T> right)

然后这样调用:

_HelperForIsValidBinarySearchTreeRecursive(root, root.Left, root.Right)

我的 C# 解决方案

public bool IsBST()
{
   return CheckBST(Root, default(T), default(T));
}
private bool CheckBST(TreeNode<T> root, T Min, T Max)
{
   if (root == null)
   {
     return true;
   }
   if (!(root.Value.CompareTo(Min) <= 0 || root.Value.CompareTo(Max) >= 1))
   {
      return false;
   }

   return CheckBST(root.Left, Min, root.Value) && CheckBST(root.Right, root.Value, Max);
}