import java.util.function.Consumer; import java.util.Queue; import java.util.LinkedList; class TreeTraversal { static class EmptyNode { void accept(Visitor aVisitor) {} void accept(LevelOrder aVisitor, Queue data) {} } static class Node extends EmptyNode { T data; EmptyNode left = new EmptyNode(); EmptyNode right = new EmptyNode(); Node(T data) { this.data = data; } Node left(Node aNode) { this.left = aNode; return this; } Node right(Node aNode) { this.right = aNode; return this; } void accept(Visitor aVisitor) { aVisitor.visit(this); } void accept(LevelOrder aVisitor, Queue data) { aVisitor.visit(this, data); } } static abstract class Visitor { Consumer> action; Visitor(Consumer> action) { this.action = action; } abstract void visit(Node aNode); } static class PreOrder extends Visitor { PreOrder(Consumer> action) { super(action); } void visit(Node aNode) { action.accept(aNode); aNode.left.accept(this); aNode.right.accept(this); } } static class InOrder extends Visitor { InOrder(Consumer> action) { super(action); } void visit(Node aNode) { aNode.left.accept(this); action.accept(aNode); aNode.right.accept(this); } } static class PostOrder extends Visitor { PostOrder(Consumer> action) { super(action); } void visit(Node aNode) { aNode.left.accept(this); aNode.right.accept(this); action.accept(aNode); } } static class LevelOrder extends Visitor { LevelOrder(Consumer> action) { super(action); } void visit(Node aNode) { Queue queue = new LinkedList<>(); queue.add(aNode); do { queue.remove().accept(this, queue); } while (!queue.isEmpty()); } void visit(Node aNode, Queue queue) { action.accept(aNode); queue.add(aNode.left); queue.add(aNode.right); } } public static void main(String[] args) { Node tree = new Node(1) .left(new Node(2) .left(new Node(4) .left(new Node(7))) .right(new Node(5))) .right(new Node(3) .left(new Node(6) .left(new Node(8)) .right(new Node(9)))); Consumer> print = aNode -> System.out.print(aNode.data + " "); tree.accept(new PreOrder(print)); System.out.println(); tree.accept(new InOrder(print)); System.out.println(); tree.accept(new PostOrder(print)); System.out.println(); tree.accept(new LevelOrder(print)); System.out.println(); } }