如何以格式良好的方式打印出树?

时间:2010-11-15 01:02:49

标签: language-agnostic data-structures tree

在树形结构中打印树的最简单方法是什么?比如...

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

即使手工格式化也很难。如何让程序以这种方式打印树?

6 个答案:

答案 0 :(得分: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 :(得分:0)

好吧,你可以尝试类似PHP的var_dump - 如果你在类似树的数组上尝试var_dump,它会为你提供一个公平的树形表示,即:

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

答案 2 :(得分:0)

虽然我自己没有尝试,graphviz有一个纯文本output format

答案 3 :(得分:0)

this answer对类似问题怎么样? 它打印出一个很好的ASCII艺术树。

或者如果你想完全图形化,可能还需要this one

答案 4 :(得分: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
}

我可能无法正确记住这一点,您可能需要稍微调整一下代码才能使其正确。

答案 5 :(得分: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 ) );
    }
}
相关问题