2017-03-26 46 views
0

我做了這個結構來表示的N叉樹:N元樹等於

public class MyTree { 
    public int data; 
    LinkedList<MyTree> children; 


    public MyTree(int data) { 
     this.data = data; 
     this.children = new LinkedList<>(); 
    } 

    public void addChild(MyTree child) { 
     this.children.addFirst(child); 
    } 

    public boolean equals(MyTree root) { } 
} 

我也做了一些其他的方法,但它們不是這種方法的核心,所以我不顯示它給你。但是,讓我們談談等於的方法: 如何檢查兩棵樹在結構和值上是否相等?我的意思是他們是平等的只有:

8    
/| \20 
9 10  
| 
20 
| 
30 
/| \ 
40 50 70 


    8    
/|\20 
9 10  
| 
20 
| 
30 
/| \ 
40 50 70 

所以我的想法是在同一時間(一個與this.tree和一個與輸入的樹)做兩個遞歸,當機能的研究探索的第一個節點比較它與第一第二樹等(他們必須尊重相同的順序和價值!)是這樣的:

public boolean equals(MyTree t) { 

    boolean result = true; 
    if (this == null && t == null) { 
     return false; 
    } 
    if (this == null || t == null) { 
     return false; 
    } 
    if (this.getValue() != t.getValue()) { 
     return false; 
    } 
    if (this.getChildren().size() != t.getChildren().size()) { 
     return false; 
    } 

    if (this.getChildren().size() == t.getChildren().size()) { 
     for (int i = 0; i < getChildren().size(); i++) { 
      MyTree object = t.getChildren().get(i); 
      MyTree object1 = this.getChildren().get(i); 
      result = object1.equals(object); 
      if (result == false) { 
       return false; 
      } 
     } 
    } 

    return result; 
} 

但我不知道如何在同一時間兩棵探索,我例如,做了一個dfs預訂,但在這種方法中,你必須同時探索兩棵樹。你能給我一個算法來同時探索兩棵樹嗎? 我的測試:

 MyTree t1 = new MyTree(8); 
     t1.addChild(new MyTree(9)); 
     t1.addChild(new MyTree(10)); 
     MyTree t2 = new MyTree(20); 
     t2.addChild(new MyTree(40)); 
     t2.addChild(new MyTree(30)); 
     MyTree t3 = new MyTree(25); 
     t3.addChild(new MyTree(80)); 
     t3.addChild(new MyTree(70)); 
     t3.addChild(new MyTree(95)); 
     t2.addChild(t3); 
     t1.addChild(t2); 

     MyTree t4 = new MyTree(8); 
     t4.addChild(new MyTree(9)); 
     t4.addChild(new MyTree(10)); 
     MyTree t5 = new MyTree(20); 
     t5.addChild(new MyTree(40)); 
     t5.addChild(new MyTree(30)); 
     MyTree t6 = new MyTree(25); 
     t6.addChild(new MyTree(80)); 
     t6.addChild(new MyTree(70)); 
     t6.addChild(new MyTree(95)); 
     t5.addChild(t6); 
     t4.addChild(t5); 
     System.out.print(t1.equals(t4)); 
+0

你知道如何遍歷列表嗎?你知道如何獲得特定索引列表的元素嗎? –

+0

是的,但是,例如,如果我使用兩個:第一棵樹一棵,第二棵樹一棵我認爲它需要第一棵樹的第一個元素,然後去第二棵樹,並得到第二棵樹的第一個元素..但我認爲它然後探索第二個樹的第二個節點,第二個樹的第三個節點,依此類推。還是我錯了? – HKing

+0

您可以檢查'children'列表是否長度相同;那麼假設它們是,你用一個'for'循環遍歷這兩個列表,對兩個'children'列表使用相同的索引。請注意,通過將其設置爲LinkedList,使事情變得更加困難,因爲在指定索引處獲取元素意味着多次遍歷整個列表。爲了避免這種情況,您需要使用't.children.iterator()'獲取這兩個列表的列表迭代器,並手動使用迭代器方法,因爲您不能使用'for'來並行執行兩個迭代器。 – ajb

回答

0

遞歸將是如下:樹僅相當於如果相應的數據等於,孩子大小是平等的,每個孩子都等於

public class MyTree { 
public int data; 
LinkedList<MyTree> children; 


public MyTree(int data) { 
    this.data = data; 
    this.children = new LinkedList<>(); 
} 

public void addChild(MyTree child) { 
    this.children.addFirst(child); 
} 

public boolean equals(MyTree root) { 
    if (root == null || root.children.size() != children.size() || data != root.data) return false; 

    Iterator<MyTree> myTreeIterator = children.iterator(); 
    Iterator<MyTree> rootTreeIterator = root.children.iterator(); 
    while (myTreeIterator.hasNext() && rootTreeIterator.hasNext()) { 
     if (!myTreeIterator.next().equals(rootTreeIterator.next())) return false; 
    } 
    return true; 
} 
} 

UPD:@Gene建議

public class MyTree { 
public int data; 
LinkedList<MyTree> children; 


public MyTree(int data) { 
    this.data = data; 
    this.children = new LinkedList<>(); 
} 

public void addChild(MyTree child) { 
    this.children.addFirst(child); 
} 

@Override 
public boolean equals(Object o) { 
    return this == o || !(o == null || getClass() != o.getClass()) && equals((MyTree) o); 
} 

public boolean equals(MyTree root) { 
    return !(root == null || data != root.data) && children.equals(root.children); 
} 
} 
+0

對不起,錯過了 – ajb

+0

我認爲你的迭代是不必要的。 'LinkedList'的'equals'方法已經實現了元素相等。你應該重寫基礎'equals(Object obj)'並使用這個事實來讓你的代碼更簡單。 – Gene

+0

我同意你的看法,但是這段代碼是OP合同的實現,首先給出了關於正確遞歸的明確見解 – wbars