I'm trying to display a tree structure in a table, and can't quite get my head around the last bit.
I have a fairly standard node class (with methods and constructors removed for clarity),
public class TreeNode<T> {
private TreeNode<?> parent;
private T data;
private List<TreeNode<?>> children = new ArrayList<>();
}
which might be populated something like this:
TreeNode<String> grandchild1 = new TreeNode<>("Grandchild 1");
TreeNode<String> grandchild2 = new TreeNode<>("Grandchild 2");
TreeNode<String> grandchild3 = new TreeNode<>("Grandchild 3");
TreeNode<String> child1 = new TreeNode<>("Child 1");
child1.addChild(grandchild1);
child1.addChild(grandchild2);
TreeNode<String> child2 = new TreeNode<>("Child 2");
child2.addChild(grandchild3);
TreeNode<String> root = new TreeNode<>("Root");
root.add(child1);
root.add(child2);
In order to print this data in a table, I would like to populate a nested List structure as follows,
[["Root", "Child 1", "Grandchild 1"],
["", "", "Grandchild 2"],
["", "Child 2", "Grandchild 3"]]
so that the data is 'flattened', and not repeated, so I will later be able to print it in a table like this:
| Root | Child 1 | Grandchild 1 |
| | | Grandchild 2 |
| | Child 2 | Grandchild 3 |
Here's what I've tried so far:
public List<List<String>> getData(TreeNode<?> root) {
List<List<String>> data = new ArrayList<>();
getData(data, root);
return data;
}
private void getData(List<List<String>> data, TreeNode<?> node) {
if (!node.isLeaf()) {
for (TreeNode<?> child : node.getChildren()) {
getData(data, child);
}
} else {
data.add(getRow(currentNode));
}
}
private List<String> getRow(TreeNode<?> node) {
Deque<String> row = new LinkedList<>();
TreeNode<?> currentNode = node;
while (!currentNode.isRoot()) {
row.addFirst(String.valueOf(currentNode.getData()));
currentNode = currentNode.getParent();
}
return new ArrayList<>(row);
}
Although this recursively collects the data to display, obviously the data will be repeated as for each row it's parent value is printed, and I will end up with this:
[["Root", "Child 1", "Grandchild 1"],
["Root", "Child 1", "Grandchild 2"],
["Root", "Child 2", "Grandchild 3"]]
What I'm struggling with is a way to decide if a certain value should be printed (repeated) or not, as I'm sure there must be an elegant solution.
There are no guarantees on the size or structure of the tree so the most generic solution would be the best. Any help would be greatly appreciated!