2016-01-25 39 views
0

我試圖在C#中實現一個樹數據結構,我在C++ 中做了100次但是在這裏當我試圖保持樹的泛型以便接受任何數據類型,我做了每個Node有它在Object類型的對象數據,如下所示:在C#中比較對象的類型「對象」

public class Node 
    { 
     public object Data; 
     public Node Right; 
     public Node Left; 

     public Node(object value) 
     { 
      NodeContent = value; 
      Right = Left = null; 
     } 
    } 

但是,當我試圖實現insert,我需要比較兩個objecs鍵入Object以知道是否在當前節點的左側或右側插入新節點。當我嘗試檢查此

if(value < childPtr.Data) 

其中value是要插入的值,我得到一個錯誤,說我不能比較Object類型的兩個對象。那麼有沒有辦法解決這個問題?

+3

如果你想使樹通用,那麼你應該使用泛型!使它成爲一個類節點其中T:IComparable '並使用'公共T數據;'。然後你可以做'value.CompareTo(childPtr.Data)'。 – Blorgbeard

+0

當你說'value

+0

@AlexanderDerck我用對象,所以我可以保持數據變量通用,所以樹會接受任何數據類型。 –

回答

3

的問題與你的做法是,Data可以是任何類型。您的設計允許您將多種類型放入同一棵樹中。所以一個節點可能有一個string,另一個可能有一個double,第三個可能有一個用戶定義類型的引用。如果您使Node構造函數爲IComparable實例,則假定樹中的所有項都是相同類型的,或者它們的IComparable接口實現知道如何比較所有可能數據類型的值。

簡而言之,你所做的將會起作用,但它並不是安全的。

你有什麼是非常類似C的事情。在C++中,你會使用模板來避免這種憎惡。在C#中,您使用泛型。

我回應了在評論中提出的建議:如果你想要一個通用的數據結構,使通用數據結構。使用內置集合,例如,如果你想要一個整數列表你寫:

var list_of_integers = new List<int>(); 

如果你想字符串列表:

var list_of_strings = new List<string>(); 

如果你想創建一個通用樹集合,你下手:

public class MyGenericTree<T> 
{ 
    public class Node 
    { 
     public T Data; 
     public Node Left; 
     public Node Right; 

     public Node(T data) 
     { 
      Data = data; 
     } 
    } 

    private readonly IComparer<T> _comparer; 

    public MyGenericTree(IComparer<T> comparer = null) 
    { 
     _comparer = comparer ?? Comparer<T>.Default; 
    } 
} 

你與創建它:

var myTree = new MyGenericTree<string>(); // or int, or whatever type 

如果你想有一個自定義的比較函數,你寫的:

// Create a tree that stores case-insensitive strings 
var myTree = new MyGenericTree<string>(StringComparer.CurrentCultureIgnoreCase); 

這迫使Data永遠是一個兼容的類型。你要麼使用該類型的默認比較器,要麼使用傳遞給構造器的比較器接口。

,做比較時,它是:

int a = _comparer.Compare(node1, node2); 
if (a < 0) 
    // node1 < node2 
else if (a > 0) 
    // node1 > node2 
else 
    // node1 == node2 

如果你確實想在樹中存儲類型化object引用,你可以隨便寫:

var myTree = new MyGenericTree<object>(some_object_comparer); 

雖然你爲什麼會想做這樣的事情有點神祕。

我知道這個仿製藥看起來有點奇怪,但是在與他們合作一天之後,你就會明白它們非常靈活並且安全。

+1

我非常同意吉姆。我的答案只是快速解決,而吉姆導致更好的方法。泛型非常適合所描述的問題。 – serhiyb

+0

@Jim Mischel謝謝,這實際上更有意義。我感謝您的幫助。 –

1

既然你需要從你的數據比較的更好的辦法是:

public class Node 
{ 
    public IComparable Data; 
    public Node Right; 
    public Node Left; 

    public Node(IComparable value) 
    { 
     Data = value; 
     Right = Left = null; 
    } 
} 

,以後你可以這樣做:

if(value.CompareTo(childPtr.Data) < 0) 
+0

我會盡力的,謝謝! –

+0

我猜CompareTo()在它們相等時返回0,當值小於Data時返回0,當Data大於值時大於0。我對嗎? –

+0

是的,你是對的。 – serhiyb