C# 设计从二叉树类继承的二叉搜索树类

C# 设计从二叉树类继承的二叉搜索树类,c#,oop,data-structures,binary-tree,binary-search-tree,C#,Oop,Data Structures,Binary Tree,Binary Search Tree,我正在用c#创建一个二叉搜索树类。我通过从二叉树类派生来创建这个类,因为二叉搜索树是一种二叉树。所以我将在二叉树类中使用大多数常用方法,并在二叉搜索树中共享它们 现在: BinaryTree类有两个方法“AddToLeft”和“AddToRight”方法,这两个方法必须能够访问该类之外的方法,即在Main方法中向二叉树添加节点。所以我把它们公之于众。这两个方法也应该可以在二进制搜索树类中访问(重用),以便根据条件向二进制搜索树添加节点 但是现在,由于Insert方法是binarysearchtr

我正在用c#创建一个二叉搜索树类。我通过从二叉树类派生来创建这个类,因为二叉搜索树是一种二叉树。所以我将在二叉树类中使用大多数常用方法,并在二叉搜索树中共享它们

现在: BinaryTree类有两个方法“AddToLeft”和“AddToRight”方法,这两个方法必须能够访问该类之外的方法,即在Main方法中向二叉树添加节点。所以我把它们公之于众。这两个方法也应该可以在二进制搜索树类中访问(重用),以便根据条件向二进制搜索树添加节点

但是现在,由于Insert方法是binarysearchtree向BST插入节点的候选方法,而AddToLeft和AddToRight则不是。因此,这两个方法不应该向BST对象上我的binarysearch树的客户端(外部世界)公开。如何设计这个类

我试过:

  • 将这两个方法密封在binarytree类中,没有任何帮助
  • 在基中声明它们为公共,在派生中保护它们。这也无济于事,因为public不能作为受保护的派生类继承
  • 请帮助设计课程

    public class BTNode
    {
        public int data;
        public BTNode Left { get; set; }
        public BTNode Right { get; set; }
        public BTNode(int data)
        {
            this.data = data;
        }
    }
    
    public class BinaryTree
    {
        public BTNode Root { get; set;}
        public BinaryTree() : this(null) { }
        public BinaryTree(BTNode node) { Root = node; }
        // this method common for its derived class too
        public void AddToLeft(BTNode current, BTNode node) 
        {
            current.Left = node;
        }
    
        // this method common for its derived class too
        public void AddToRight(BTNode current, BTNode node)
        {
            current.Right = node;
        }
    }
    
    public class BinarySearchTree : BinaryTree
    {       
        public BinarySearchTree(int val)
        {
            Root = new BTNode(val);    
        }
        public void Insert(int val)
        {
            BTNode node = new BTNode(val);
    
            if (Root.data >= val)
                base.AddToLeft(Root, node); // I should be able to call this method here
            else
                base.AddToRight(Root, node); // I should be able to call this method here
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            BinaryTree bt = new BinaryTree();
            BTNode root = new BTNode(3);
            BTNode node1 = new BTNode(4);
            BTNode node2 = new BTNode(7);
    
            bt.AddToLeft(root,node1); // i should be able to access this method here.
            bt.AddToLeft(root, node2); // i should be able to access this method here.
    
            BinarySearchTree bst = new BinarySearchTree(6);
            bst.Insert(4);
            bst.Insert(8);
    
            // This is the problem.
            // these two methods should not be visible on the bst object.
            // insertion to bst is done only through insert() method
            // but these two methods should be accessible inside the binarysearchtree class
            // to add the nodes.
            bst.AddToLeft(root,node1); // i should not access this method here on this object
            bst.AddToRight(root, node2); // i should not access this method here on this object
        }
    }
    

    当您键入代码时,您试图做的是自相矛盾的。你是说你的类是一种
    BinaryTree
    ,但你不想履行使它成为
    BinaryTree
    的合同

    我可能不会从
    BinaryTree
    派生,而是在
    BinarySearchTree
    类中有一个私有字段,该字段保存
    BinaryTree
    ,并通过
    BinaryTree
    中的公共访问器公开要公开的功能(因此,
    BinarySearchTree
    不再是一种二叉树,但仍然可以通过使用
    BinaryTree
    实例初始化的私有字段访问该功能)

    我当然可以理解将
    BinarySearchTree
    作为
    BinarySearchTree
    的一种类型的吸引力,但你要么放弃这两种方法的封装,要么放弃对基类型的分类。如果你不提供与它相同的外部API,你就不能声称满足对基类型分类的要求


    如果您真的希望能够尝试执行上述操作,您可以覆盖您不希望客户端使用的方法,并从这些方法中抛出
    invalidoOperationException
    。但这并不十分优雅,因为它在编译时帮不上忙,只会在运行时抱怨,这是一种不谨慎的设计。

    请尝试我们正在删除AddToLeft和AddToRight方法的私有关键字,而不是public。因为私有方法仅对基类可见


    感谢更多关于这个矛盾的内容——这是一个形而上学的问题:如果BinarySearchTree的定义是它必须能够执行左和右加法,那么BinarySearchTree不是BinaryStree。正如您所知,BinarySearchTree是一个结构,每个节点都有两个子节点。BinarySearchTree不是BinaryStree,而是一个基于键的树使用二进制树进行内部存储的orted列表


    第一个是结构,第二个是更高级别的结构,具有特定的内部存储结构和算法。BinarySearchTree可能是字典中最好的子类,其中KeyType是索引类型,ValueType是存储在每个节点上的类型(可以是集合)。您希望能够向集合中添加具有键的元素,并在以后通过该键将它们拉回来,从而获得一些额外的好处(可能是排序遍历,等等)。这是一个字典扩展,而不是BinaryTree扩展,所以你的方法就是这样,我将实现IDictionary。

    不,我希望这两个方法即使在BinaryTree类之外也能被访问,这是在我的示例中给出的主方法中是的,当BinarySearchTree是BinaryTree的一种类型时,你的评论是有意义的,它必须遵守BinaryTree给出的契约。因此,我倾向于组合而不是继承。