2012-12-25 179 views
0

我正在c#中創建一個二叉搜索樹類。我通過派生二叉樹類來創建類,因爲二叉搜索樹是一種二叉樹。因此,我將在二叉樹類中使用大多數常用方法,並在二叉搜索樹內共享它們。 BinaryTree類有兩種方法「AddToLeft」和「AddToRight」方法,這兩種方法必須能夠在這個類之外訪問,即在Main方法中向二叉樹添加節點。所以我讓他們公開。並且這兩種方法也應該在二元搜索樹類(reusing)內部可訪問以基於條件向二元搜索樹中添加節點。設計從二叉樹類繼承的二叉搜索樹類

但是現在,由於Insert方法是binarysearchtree將節點插入BST的候選者,但AddToLeft和AddToRight不是。所以這兩種方法不應該暴露給BST對象上的二進制搜索樹的客戶端(外部世界)。如何設計這個班級?

我想:

  1. 使得在二叉樹類密封這兩種方法,它並沒有幫助。
  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 
    } 
} 

回答

1

你在輸入代碼時試圖做的事情是一個矛盾。你說你的班級是BinaryTree,但你不希望履行合同,使其成爲BinaryTree

我可能會做不會從BinaryTree獲得,而是有一個在你的BinarySearchTree類持有一個BinaryTree私人領域和揭露你想在BinaryTree通過公共存取暴露的功能(所以BinarySearchTree不再是一個類型的二叉樹,但仍然有通過與BinaryTree的實例初始化一個私有字段訪問功能。)

我當然可以理解使得BinarySearchTree一種類型的BinaryTree的吸引力,但你要麼放棄那些封裝兩種方法或基本類型的分類。當您不提供相同的外部API時,您不能聲稱符合基本類型的分類要求。

如果你真的想能夠像上面那樣做事情,你可以重寫你不想讓客戶使用的方法,並從這些方法中拋出InvalidOperationException。但是這並不是很優雅,因爲它在編譯時不會幫助你,而且只會在運行時抱怨,這不是審慎的設計。

+0

是的,您的意見是有道理的,當BinarySearchTree是一種BinaryTree,它必須遵守BinaryTree給出的合同。所以我會比繼承更喜歡構圖。 –

0

嘗試使用AddToLeft和AddToRight方法的private關鍵字而不是public。因爲私有方法只對基類可見。

感謝

+0

不,我想要在BinaryTree類之外訪問這兩種方法,那在我的Main方法中,就像我的例子中給出的那樣 –

0

更多的矛盾 - 這是一個形而上學的問題:一個BinarySearchTree不是二叉樹,如果一個二叉樹的定義是,它必須能夠進行左右增加。如你所知,BinaryTree是一個結構,它有每個節點的兩個子節點。BinarySearchTree不是BinaryTree,而是基於密鑰的排序列表,使用 BinaryTree作爲內部存儲。

第一個是結構,第二個是具有特定內部存儲結構和算法的更高級別的結構。 BinarySearchTree可能是Dictionary中最好的子類,其中KeyType是索引類型,ValueType是存儲在每個節點(可能是一個集合)的類型。你希望能夠通過一個鍵添加元素到集合中,然後通過這個鍵將它們拉回來,並帶來一些額外的好處(也許有序的遍歷等)。這是一個字典擴展,而不是一個BinaryTree擴展,所以你的方法來結束它的方式,我會實現IDictionary。