2012-03-15 73 views
1

我想用ANTLR樹命令和遞歸遍歷一棵樹。我現在的代碼是:遞歸深入遍歷一棵樹第一個問題

public void traverseTree(Tree tree){ 
     int counter = 0; 
     System.out.println(tree.toString()); 
     if (tree.getChildCount() > 0 && tree.getChild(0) != null){ 
      System.out.println(tree.toString() + counter++); 
      tree = tree.getChild(0); 
      traverseTree(tree); 

     } 
     while (tree.getParent().getChild(tree.getChildIndex() + 1) != null){ 
      System.out.println(tree.toString() + counter++); 
      tree = tree.getParent().getChild(tree.getChildIndex() + 1); 
      traverseTree(tree); 

     } 
    } 

但是,它不工作。我在樹中獲得了很多條目,但是沒有明顯的順序。任何人都可以看到我要去哪裏嗎?

謝謝。

編輯:

評論我低於發應該是在這裏開始:

對不起,我應該取出的打印報表,他們就在那裏嘗試和調試。我遇到的問題是,它應該只搜索它開始的節點以及該節點的所有兄弟節點,它不應該升級,但它會打印所有內容。 (我會把它編入主文件,應該在那裏開始,對不起)。

我設法得到的代碼工作,最終像這樣:

public void traverseTree(Tree tree){ 
     System.out.println(tree); 
     if (tree.getChild(0) != null){ 
      traverseTree(tree.getChild(0)); 
     } 
     if(tree.getParent().getChildCount() > 1){ 
      if(tree.getParent().getChild(tree.getChildIndex() + 1) != null) 
      traverseTree(tree.getParent().getChild(tree.getChildIndex() + 1)); 
     } 
    } 
+0

「深度優先」...您是指級別順序?顛倒秩序?我很困惑..其他的可能性是預先訂購,訂購,訂購 – varatis 2012-03-15 17:02:08

回答

2

確保永不升級的最簡單方法是確保您永遠不會撥打getParent()。如果你不知道有一個較高的水平,你不能去那裏。

public void traverseTree(Tree tree) { 

    // print, increment counter, whatever 
    System.out.println(tree.toString()); 

    // traverse children 
    int childCount = tree.getChildCount(); 
    if (childCount == 0) { 
     // leaf node, we're done 
    } else { 
     for (int i = 0; i < childCount; i++) { 
      Tree child = tree.getChild(i); 
      traverseTree(child); 
     } 
    } 
} 

遞歸的要點是你不需要回去。當此級別的traverseTree()完成時,上一級的循環將繼續到下一個兄弟。

(請注意,if實際上並不是必須的,除非當你到達葉節點時你想做一些特殊的事情,我只是把它放在那裏,所以評論會使它明白髮生了什麼事情,從概念上講,它總是一個遞歸中的好主意,通過確定如何知道何時停止遞歸來開始。)

+0

但是,這是事情,我從來沒有使用getParent(),除非我做getParent。getChild(getChildIndex()+ 1),它只是將其移動到下一個兄弟(似乎沒有另一種方式來做到這一點)。 – djcmm476 2012-03-15 17:49:50

+0

你不需要移動到下一個兄弟姐妹。父母級別的循環會照顧到這一點。 – 2012-03-15 17:53:40

+0

(當然,你實際上必須有一個循環,我想沒有循環就可以做到這一點,但我不知道你爲什麼要這樣做) – 2012-03-15 17:55:07

0

試試這個:

int counter = 0; 
public void traverseTree(Tree tree) { 

    for (int i=0; i<tree.getChildCount(); i++) { 
     Tree child = tree.getChild(i); 
     System.out.println(tree.toString() + counter++); 
     traverseTree(tree); 
    } 
} 
2

它看起來像你打印出相同的節點幾次。如果你只是想爲你去到打印出來的節點,

1 
2 3 
4 5 6 

Depth first - 1 2 4 5 3 6 
Breadth first - 1 2 3 4 5 6 

//For depth first 
public void traverseTree(Tree tree){   
    System.out.println(tree.toString()); 
    for (int x = 0; x < tree.getChildCount(); x++) 
     traverseTree(tree.getChild(x)); 
} 

要切換到4 5 6 2 3 1,只需移動的println後for循環。

+0

對不起,我應該刪除打印語句,他們只是在那裏嘗試和調試它。我遇到的問題是,它應該只搜索它開始的節點以及該節點的所有兄弟節點,它不應該升級,但它會打印所有內容。 (我會把它編入主文件,應該在那裏開始,對不起)。 – djcmm476 2012-03-15 17:28:41

+0

@Incredidave Thomas的解決方案(幾乎)可以在你給它的任何節點上工作(它應該有null退出語句)。如果你想從小孩開始,只需傳遞它而不是根。您確實需要更具體地瞭解您想要訪問每個節點的方式,您打算在那裏做什麼以及按照什麼順序。 – varatis 2012-03-15 18:04:17

+0

我假設孩子們是非空的,所以它會因爲getChildCount()爲0而終止。在任何情況下,它都不回答實際問題。 – Thomas 2012-03-15 21:00:47