2010-11-15 35 views
5

在樹形結構中打印樹的最簡單方法是什麼?如...如何以一種很好的格式打印出樹?

    some root 
      / |   \ 
      child1 child2  child 3 
     /
     anotherchild    /\ 
          yup  another 

即使手工格式化也很難。你怎麼能讓程序以這種方式打印一棵樹?

+0

您應該更改與語言無關的標記,因爲有些語言/環境在本地執行。 – 2010-11-15 02:17:38

回答

0

那麼,你可以嘗試像PHP的的var_dump - 如果你嘗試樹狀陣列上的var_dump,它會給你樹一個公平的代表性,那就是:

root { 
    child1 { 
     anotherchild 
    } 
    child2 
    child3 { 
     yup 
     another 
    } 
} 
5

除非有一些不錯的圖形庫可以使用,否則在描述方式中代表層次結構時會遇到很多麻煩。

假設您想要將其打印到控制檯或文件中,您必須與預先計算整個樹中所有數據元素的長度進行抗衡,以便正確排列它們。你怎麼處理像換行一樣的東西?

更好的方法是垂直表示樹,使用縮進顯示子元素。

Root 
    - Child1 
     - Grandchild1 
     - Grandchild2 
    - Child2 
     - Grandchild3 
     - Grandchild4 

這是更簡單的代碼,更容忍像linewrap這樣的東西 - 因爲一行上只有一個元素。這是文件夾瀏覽器或XML文檔如何顯示其分層數據。

要做到這種方式,你做一個深度優先遍歷和打印出來的節點遞歸步驟之前:

public void PrintNode(TreeNode node) 
{ 
    PrintNode(node, 0); 
} 

private void PrintNode(TreeNode node, int indentation) 
{ 
    // Print the value to the console/file/whatever 
    // This prefixes the value with the necessary amount of indentation 
    Print(node.Value, indentation); 

    // Recursively call the child nodes. 
    foreach(TreeNode childNode in node.Children) 
    { 
     PrintNode(childNode, indentation + 1); // Increment the indentation counter. 
    } 
} 

希望幫助

+1

當然,您會將縮進深度作爲第二個參數傳遞給'PrintNode'(對於客戶端調用默認值爲0,並在遞歸調用中添加一個級別)?那麼你不必手動減少它。 – Zecc 2010-11-15 01:19:36

+0

這對於以請求的格式打印樹木沒有用處。 – 2010-11-15 01:46:21

+0

@Zecc - 這就是我最後一句話的意思(以我爲例)。我試圖用與語言無關的方式編寫它,而沒有指定如何縮進或打印實際上完成。我實際上通常會有一個公共調用,用0調用一個私有覆蓋來隱藏消費者。 – sheikhjabootie 2010-11-15 01:52:10

0

如何this answer到類似的問題? 它打印一個不錯的ASCII藝術樹。

或者可能this one如果你想要完全圖形?

0

去年我不得不這樣做,寫了一個家譜應用程序。在網上找到了一個有幫助的java教程,但是我的Google-fu今天失敗了,所以我不得不簡單地解釋它。

這只是一個遞歸算法,它根據子節點調整父節點的位置。在僞代碼是這樣的:

positionNode (node,x,y) { 
    foreach (child in node.children) { 
     positionNode(child,x,y+1) 
     x ++ 
    } 
    node.x = (x-1)/2 
    node.y = y 
} 

我可能無法正確記住這一點,你可能需要調整一下代碼,得到它的權利。

0

以下的答案必須是在Java中,但它是如此簡單,它可以很容易地被轉錄成其他語言:

public interface Function1<R, T1> 
{ 
    R invoke(T1 argument1); 
} 

public interface Procedure1<T1> 
{ 
    void invoke(T1 argument1); 
} 

public static <T> void dump(T node, Function1<List<T>,T> breeder, 
     Function1<String,T> stringizer, Procedure1<String> emitter) 
{ 
    emitter.invoke(stringizer.invoke(node)); 
    dumpRecursive(node, "", breeder, stringizer, emitter); 
} 

private static final String[][] PREFIXES = { { " ├─ ", " │ " }, { " └─ ", " " } }; 

private static <T> void dumpRecursive(T node, String parentPrefix, 
     Function1<List<T>,T> breeder, Function1<String,T> stringizer, 
     Procedure1<String> emitter) 
{ 
    for(Iterator<T> iterator = breeder.invoke(node).iterator(); iterator.hasNext();) 
    { 
     T childNode = iterator.next(); 
     String[] prefixes = PREFIXES[iterator.hasNext()? 0 : 1]; 
     emitter.invoke(parentPrefix + prefixes[0] + stringizer.invoke(childNode)); 
     dumpRecursive(childNode, parentPrefix + prefixes[1], breeder, stringizer, emitter); 
    } 
} 

它產生以下輸出:

Automobile 
├─ Passenger Vehicle 
│ ├─ Light Passenger Vehicle 
│ │ ├─ Two Wheeled 
│ │ │ ├─ Moped 
│ │ │ ├─ Scooter 
│ │ │ └─ Motorcycle 
│ │ ├─ Three Wheeled 
│ │ └─ Four Wheeled 
│ │  ├─ Car 
│ │  ├─ Station Wagon 
│ │  ├─ Pick-up Truck 
│ │  └─ Sports Utility Vehicle 
│ └─ Heavy Passenger Vehicle 
│  ├─ Bus 
│  │ ├─ Single-Deck Bus 
│  │ │ ├─ Mini Bus 
│  │ │ └─ Big Bus 
│  │ └─ Double-Deck Bus 
│  └─ Coach 
│   ├─ Deluxe 
│   └─ Air-Conditioned 
└─ Goods Vehicle 
    ├─ Light Goods Vehicle 
    │ ├─ Delivery Van 
    │ ├─ Light Truck 
    │ └─ Tempo 
    │  ├─ Three Wheeler Tempo 
    │  └─ Four Wheeler Tempo 
    └─ Heavy Goods Vehicle 
     ├─ Truck 
     └─ Tractor Trailer 

...如果您使用以下示例程序調用它:

final class Scratch 
{ 
    static class Node 
    { 
     String name; 
     List<Node> children; 

     Node(String name, Node... children) 
     { 
      this.name = name; 
      this.children = Arrays.asList(children); 
     } 
    } 

    public static void main(String[] args) 
    { 
     Node tree = new Node("Automobile", 
       new Node("Passenger Vehicle", 
         new Node("Light Passenger Vehicle", 
           new Node("Two Wheeled", 
             new Node("Moped"), 
             new Node("Scooter"), 
             new Node("Motorcycle")), 
           new Node("Three Wheeled"), 
           new Node("Four Wheeled", 
             new Node("Car"), 
             new Node("Station Wagon"), 
             new Node("Pick-up Truck"), 
             new Node("Sports Utility Vehicle"))), 
         new Node("Heavy Passenger Vehicle", 
           new Node("Bus", 
             new Node("Single-Deck Bus", 
               new Node("Mini Bus"), 
               new Node("Big Bus")), 
             new Node("Double-Deck Bus")), 
           new Node("Coach", 
             new Node("Deluxe"), 
             new Node("Air-Conditioned")))), 
       new Node("Goods Vehicle", 
         new Node("Light Goods Vehicle", 
           new Node("Delivery Van"), 
           new Node("Light Truck"), 
           new Node("Tempo", 
             new Node("Three Wheeler Tempo"), 
             new Node("Four Wheeler Tempo"))), 
         new Node("Heavy Goods Vehicle", 
           new Node("Truck"), 
           new Node("Tractor Trailer")))); 
     dump(tree, n -> n.children, n -> n.name, s -> System.out.println(s)); 
    } 
}