Reputation: 3735
I have a tree with nodes, and each node contains a list with nodes, and each node in those lists contain nodes... It can be 10 levels deep, with around 100 node objects.
I've tried to iterate to find all individual node objects but most guides covers binary trees.. It's just overwhelming. If anyone has some pseudo code or can point me in the right direction I would be very glad. Classes below (sorry about the bad formatting):
Node
public class Node {
public String text;
public LinkedList<Node> nodes;
public Node() {
this.nodes = new LinkedList<Node>();
}
public Node(String data) {
this();
this.text = data;
}
}
Tree
public class Tree {
public LinkedList<Node> nodes;
public String text;
public Tree() {
nodes = new LinkedList<Node>();
}
public Tree(String data) {
this();
this.text = data;
}
}
Program
public class Main {
public static void main(String[] args) {
LinkedList<Tree> trees = new LinkedList<Tree>();
trees.add(new Tree("Root 1"));
trees.get(0).nodes.add(new Node("Node 1"));
trees.get(0).nodes.add(new Node("Node 2"));
trees.get(0).nodes.add(new Node("Node 3"));
trees.get(0).nodes.get(0).nodes.add(new Node("Node 1:Child 1"));
trees.get(0).nodes.get(1).nodes.add(new Node("Node 2:Child 1"));
trees.get(0).nodes.get(2).nodes.add(new Node("Node 3:Child 1"));
for (Tree tree : trees) {
tree.nodes.. // find all node-objects
}
}
}
Upvotes: 0
Views: 318
Reputation: 186
This can be done by recursion. Since you have maximum depth of 10 and max elements = 100, recursion should not give any performance issues. Sample code to do this:
List<Node> flattenTree(List<Node> nodes){
List<Node> allNodes=new LinkedList<>(nodes) ;
for(Node node:nodes){
{
if(node.getNodes()!=null)
allNodes.addAll(flattenTree(node.getNodes()));
}
return allNodes;
}
Call this using:
List<Node> allNodes = flattenTree(tree.getNodes);
allNodes will contain all the nodes of this tree.
Upvotes: 2
Reputation: 76631
You just need to track the depth of the nodes:
LinkedList<Node> currentNodes = new LinkedList<Node>();
currentNodes.add(root);
int depth = 0;
while depth < 10 {
depth++;
int size = currentNodes.size();
for (int i = 0; i < size; i++) {
Node current = currentNodes.removeFirst();
//Do something with current
for (int j = 0; j < current.nodes.size(); j++) {
currentNodes.addLast(current.nodes.get(j));
}
}
}
Upvotes: 1
Reputation: 16806
Just out of curiosity, what kind of problem would require a data structure like this?
Something like this in main
should set you on the right track:
// set up the master list of all nodes and the list of unvisited nodes
// with the base tree's node.
List<Node> allTheNodes = new LinkedList<>();
allTheNodes.add(tree.node);
List<Node> unvisited = new LinkedList<>();
unvisited.add(tree.node);
while (!unvisited.isEmpty())
{
// while our unvisited list is not empty, visit the first node in the list
// and add all of its subnodes to both the list of nodes to visit and the master list of nodes.
Node currentNode = unvisited.get(0);
allTheNodes.addAll(currentNode.nodes);
unvisited.addAll(currentNode.nodes);
unvisited.remove(currentNode);
}
// now, allTheNodes should have all of your nodes in it.
Upvotes: 1
Reputation: 9650
You can do this by using recursion:
interface TreeOp {
void apply(Tree tree);
}
...
void traverse(Tree tree, TreeOp op) {
op.apply(tree);
for (Tree child: tree.nodes) {
traverse(child, op);
}
}
...
for (Tree tree : trees) {
traverse(tree, (tree) -> {
doSomethingWith(tree);
});
}
UPDATE:
Actually, you can use the Consumer interface instead of defining a new one:
void traverse(Tree tree, Consumer<Tree> op) {
op.accept(tree);
for (Tree child: tree.nodes) {
traverse(child, op);
}
}
UPDATE 2:
And traverse could be a method of Tree:
void traverse(Consumer<Tree> op) {
op.accept(this);
for (Tree child: nodes) {
traverse(child, op);
}
}
Upvotes: 1