2012-06-30 39 views
2

首先我已經搜索了關於java中泛型類型的用法,但是我發現的答案太簡單或複雜了。所以這是我確切的問題。在Java中使用泛型類型的樹實現

我有三個類分別PerfectTreeControl,Tree和Entry。

樹有

public class Tree<K> { 
    public Entry <K> root; 

條目已

public class Entry<K> { 
    public K element; 
    public Entry<K> parent, left_child, right_child; 


    public Entry(K element) { 
     this.element = element; 
    } 
    public Entry(K element, Entry<K> left, Entry<K> right) { 
     left_child = left; 
     right_child = right; 
     this.element = element; 
    } 

我想了解什麼是進入母體和Entry <ķ>父母之間有什麼區別?我知道K element可以用作整數,字符串或任何我想要的,但是對於對象來說是否也是這樣?我試圖使用不帶參數的Entry變量,它只是說Entry是一個原始類型,應該參數化並且它仍然沒有錯誤地工作。

我的第二個問題是關於檢查樹是否完美。下面是一些代碼到目前爲止,我已經試過:

public class PerfectTreeControl { 

    public static boolean isPerfect(Tree<String> tree) { 
     Tree t1 = new Tree(); 
     if(t1.isFull(tree.root)) { 
      int depth = t1.height(tree.root); 
      return t1.everyLeafHasSameDepth(tree.root, depth); 
     } 
     else 
      return false; 
    } 
    } 





public class Tree<K> { 
    public Entry <K> root; 

    public boolean isLeaf(Entry e) { 
     return e.left_child == null && 
       e.right_child == null; 
    } 

    public int height(Entry e) { 
     if(e == null || 
       e.left_child == null && 
       e.right_child == null) 
      return 0; 
     int left = height(e.left_child); 
     int right = height(e.right_child); 

     return 1 + Math.max(left, right); 
    } 

    public boolean isFull(Entry base) { 
     if(isLeaf(base)) 
      return true; 
     else 
      if(base.left_child != null && base.right_child != null) { 
       return isFull(base.left_child) && 
         isFull(base.right_child); 
      } else { 
       return false; 
      } 
    } 


    public int depth(Entry e) { 
     if(e == root) { 
      return 0; 
     } else { 
      return 1 + depth(e.parent); 
     } 
    } 

    public boolean everyLeafHasSameDepth(Entry base, int depth) { 
     if(base == null) 
      return false; 
     else if(isLeaf(base)) 
      return depth(base) == depth; 
     else { 
      return 
        everyLeafHasSameDepth(base.left_child, depth) && 
        everyLeafHasSameDepth(base.right_child, depth); 
     } 
    } 
  • 入門級(我寫在頁面的頂部)如你所見,在PerfectTreeControl類isPerfect方法使用樹-String-樹作爲參數,我不知道它是什麼。在Tree類中,我嘗試了Entry,並且再次沒有區別。代碼將無法正常工作,我完全困惑。
+0

你不應該擔心原始類型。它們只是爲了向後兼容,並且不應該使用通用類型的原始版本。 (即在你的代碼中,無處不在使用'Entry '。) – millimoose

+0

定義通用對象有什麼意義?更清楚的是,將對象定義爲泛型而不是普通對象有什麼優勢?對象已經可以將你在類中定義的任何東西當作一個變量,字符串,int等等。我錯過了什麼? – nihirus

+0

@nihirus:如果您在任何地方使用普通對象,則每次需要將值轉換爲所需類型時,都需要執行某些操作。 – Tudor

回答

3

Java中的泛型基本上是一種命名對象中的特定類的方法,在知道哪個類直到該對象被聲明爲止。這很有用,因爲它允許編譯器在對該類的引用中強制執行一致性。

更具體地說,在Entry<K>類,您引用K任何時候,Java編譯器將強制執行K類型的所有引用,其實視爲K類型。例如,如果創建Entry<String>類型的對象,則該對象的element成員必須是String類型的成員,parent成員的類型必須是Entry<String>等。如果您有返回K的方法,則編譯器會識別該對象返回值是String。如果編譯器在這裏看到不一致性 - 比如說,如果你試圖將member的值設置爲Integer - 它會報錯。

請記住,我在上面的例子中描述的品質都參照您定義的特定Entry<String>對象。如果您改爲定義Entry<Integer>而不更新Entry類,則會在該新對象內執行一致性 - 除非這一次使用K含義Integer

如果您創建的對象沒有爲K指定類型參數,那麼您正在使用「原始類型」。這樣可以防止編譯器執行一致性規則,並且會假定K的類型爲Object。這意味着你將不得不開始擔心投射,這可能很難做到。

要檢查樹是否已滿(或「完美」),最直觀的方法是遞歸。在這種情況下使用的遞歸規則是「如果一棵樹的孩子是完美的並且具有相同的深度,那麼樹就是完美的。」