(In case you want to avoid the lengthy explanation, all I am looking for is a level order traversal for a generic-tree(n-ary tree) in java. The code supplied works and needs
The following seems to work. For extra credit, iteration can be done with an enhanced for loop, and aborted at any time. You might want to add access modifiers.
import java.util.*;
class NaryTree {
final int data;
final List<NaryTree> children;
public NaryTree(int data, NaryTree... children) {
this.data = data;
this.children = Arrays.asList(children);
}
static class InOrderIterator implements Iterator<Integer> {
final Queue<NaryTree> queue = new LinkedList<NaryTree>();
public InOrderIterator(NaryTree tree) {
queue.add(tree);
}
@Override
public boolean hasNext() {
return !queue.isEmpty();
}
@Override
public Integer next() {
NaryTree node = queue.remove();
queue.addAll(node.children);
return node.data;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
Iterable<Integer> inOrderView = new Iterable<Integer>() {
@Override
public Iterator<Integer> iterator() {
return new InOrderIterator(NaryTree.this);
}
};
}
Test code:
public class Test {
public static void main(String[] args) throws Exception {
NaryTree tree = new NaryTree(100,
new NaryTree(90,
new NaryTree(20),
new NaryTree(30)
), new NaryTree(50,
new NaryTree(200),
new NaryTree(300)
), new NaryTree(70)
);
for (int x : tree.inOrderView) {
System.out.println(x);
}
}
}
Level-order traversal using Queue:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Queue;
import java.util.stream.Collectors;
public class LevelOrderTraversal {
static class Node {
int data;
Node children[];
Node(int data, int n) {
children = new Node[n];
this.data = data;
}
}
public static void main(String[] args) {
/*
1
/ | \
2 3 4
/ | \
5 6 7
*/
int n = 3;
Node root = new Node(1, n);
root.children[0] = new Node(2, n);
root.children[1] = new Node(3, n);
root.children[2] = new Node(4, n);
root.children[0].children[0] = new Node(5, n);
root.children[0].children[1] = new Node(6, n);
root.children[0].children[2] = new Node(7, n);
List<List<Integer>> levelList = levelOrder(root);
for (List<Integer> level : levelList) {
for (Integer val : level) {
System.out.print(val + " ");
}
System.out.println();
}
}
public static List<List<Integer>> levelOrder(Node root) {
List<List<Integer>> levelList = new ArrayList<>();
if (root == null) {
return levelList;
}
Queue<Node> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
int n = queue.size();
List<Integer> level = new ArrayList<>();
while (n-- > 0) {
Node node = queue.remove();
level.add(node.data);
queue.addAll(Arrays.stream(node.children).filter(Objects::nonNull).collect(Collectors.toList()));
}
levelList.add(level);
}
return levelList;
}
}