【问题标题】:Is Valid Generic Binary Search Tree with Recursion是具有递归的有效通用二叉搜索树
【发布时间】:2020-05-29 21:55:35
【问题描述】:

为了检查 二叉搜索树 的有效性,我使用了一种方法。但是当针对有效的二叉搜索树进行测试时,该方法总是返回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);
    }
}

【问题讨论】:

    标签: c# generics recursion binary-search-tree icomparable


    【解决方案1】:

    你的问题在这里:

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

    我猜你的初衷是用root比较左右?

    基于此: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)
    

    【讨论】:

    • 如果我们可以在第一次调用中将 null 传递给 lower 和 upper ,那么该私有函数将起作用。但是,我在此示例中使用整数作为节点类型。由于我们不能将 null 传递给整数参数(下限和上限),因此我将下限和上限与根进行比较。但它不起作用。
    【解决方案2】:

    我的 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);
    }
    

    【讨论】:

      猜你喜欢
      • 2013-04-14
      • 2014-01-02
      • 2021-07-03
      • 2019-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多