La siguiente respuesta está en java, pero es tan simple que fácilmente puede ser transcrito a otros idiomas:
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);
}
}
Se produce el siguiente resultado:
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
...si se invoca utilizando el siguiente programa de ejemplo:
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));
}
}
debe cambiar la etiqueta independiente del idioma, ya que hay lenguajes/entornos en los que esto se implementa de forma nativa. –