1

私はc#でバイナリ検索ツリークラスを作成しています。二分探索木は二分木の一種であるため、二分木クラスから派生してクラスを作成しています。したがって、私はバイナリツリークラス内にほとんどの一般的なメソッドを持ち、バイナリ検索ツリー内でそれらを共有します。

現在:BinaryTreeクラスには「AddToLeft」メソッドと「AddToRight」メソッドの2つのメソッドがあります。これらの2つのメソッドは、このクラスの外部、つまりMainメソッドでバイナリツリーにノードを追加するためにアクセスできる必要があります。だから私はそれらを公開しました。また、これら2つのメソッドは、条件に基づいて二分探索木にノードを追加するために、二分探索木クラス内でアクセス可能(再利用)である必要があります。

ただし、InsertメソッドはbinarysearchtreeがノードをBSTに挿入するための候補であるため、AddToLeftとAddToRightはそうではありません。したがって、これら2つのメソッドは、BSTオブジェクト上のbinarysearchツリーのクライアント(外部)に公開されるべきではありません。このクラスを設計する方法。

私は試した:

  1. これらの2つのメソッドをbinarytreeクラスで封印したので、役に立ちませんでした。
  2. それらをベースで公開し、派生で保護することを宣言しました。派生クラスで保護されているようにパブリックを継承できないため、これも役に立ちませんでした。

クラスのデザインを手伝ってください。

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
    }
}
4

3 に答える 3

2

コードを入力するときに何をしようとしているのかは矛盾しています。あなたはあなたのクラスが一種であると言ってBinaryTreeいますが、それを作る契約を尊重したくありませんBinaryTree

私がおそらく行うことは、派生ではなく、代わりに、クラスにを保持し、パブリックアクセサーを介して公開したい機能を公開するBinaryTreeプライベートフィールドを持っていることです(したがって、バイナリツリーのタイプではありませんが、のインスタンスで初期化されたプライベートフィールドを介した機能。)BinaryTreeBinarySearchTreeBinaryTreeBinarySearchTreeBinaryTree

BinarySearchTreeタイプを作成することの魅力は確かに理解できBinaryTreeますが、これら2つの方法のカプセル化または基本タイプの分類をあきらめることになります。同じ外部APIを提供していない場合、基本タイプの分類の要件を満たしていると主張することはできません。

上記のようなことを本当に実行できるようにしたい場合は、クライアントに使用させたくないメソッドをオーバーライドして、InvalidOperationExceptionそれらのメソッドからsをスローすることができます。ただし、これはコンパイル時に役立つわけではなく、実行時にのみ文句を言うため、賢明な設計ではないため、あまりエレガントではありません。

于 2012-12-25T08:20:17.100 に答える
0

publicの代わりにAddToLeftメソッドとAddToRightメソッドの両方のprivateキーワードを使用してみてください。プライベートメソッドは基本クラスにのみ表示されるためです。

ありがとう

于 2012-12-25T11:05:24.337 に答える
0

矛盾の詳細-それは形而上学の問題です:BinaryTreeの定義が左と右の追加を実行できなければならないということである場合、BinarySearchTreeはBinaryTreeではありません。ご存知のように、BinaryTreeは、各ノードの2つの子ノードを持つ構造です。BinarySearchTreeはBinaryTreeではなく、内部ストレージにBinaryTreeを 使用するキーベースのソート済みリストです。

1つは構造であり、2つ目は、特定の内部ストレージ構造とそれに対応するアルゴリズムを備えた高レベルの構造です。BinarySearchTreeは、おそらくディクショナリからサブクラス化するのが最適です。ここで、KeyTypeはインデックスタイプであり、ValueTypeは各ノードに格納されているタイプです(セットの場合もあります)。コレクションにキーを持つ要素を追加し、後でそのキーによって要素を引き戻せるようにしたい場合は、いくつかの追加の利点があります(ソートされたトラバーサルなど)。これは辞書の拡張機能であり、BinaryTreeの拡張機能ではないので、それをまとめるアプローチが道のりであり、私はIDictionaryを実装します。

于 2013-01-20T16:56:28.750 に答える