Skip to content

Instantly share code, notes, and snippets.

@programmerr47
Last active September 26, 2016 08:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save programmerr47/1775c4c4c9876bea7b8777d77e16cd10 to your computer and use it in GitHub Desktop.
Save programmerr47/1775c4c4c9876bea7b8777d77e16cd10 to your computer and use it in GitHub Desktop.
Iterator for "going" through tree by using DFS.
//sample Node.class of three
class Node {
Object data;
Node left;
Node right;
public boolean isLeaf() {
return left == null && right == null;
}
}
class DepthFirstIterator implements Iterator<Node> {
private static final NodeAnalyzer analyzer = new NodeAnalyzer();
private final List<Node> depthChain = new ArrayList<>();
private final Node rootNode;
private Node currentNode;
private final int expectedTreeSize;
public DepthFirstIterator(Node rootNode) {
this.rootNode = rootNode;
this.currentNode = rootNode;
this.expectedTreeSize = analyzer.nodeSize(rootNode);
}
@Override
public boolean hasNext() {
return !depthChain.isEmpty() || currentNode != null;
}
@Override
public Node next() {
checkForComodification();
Node result = currentNode;
goToNext();
return result;
}
private void goToNext() {
if (currentNode.isLeaf()) {
goUp();
} else {
depthChain.add(currentNode);
if (currentNode.left != null) {
currentNode = currentNode.left;
} else {
currentNode = currentNode.right;
}
}
}
private void goUp() {
if (depthChain.isEmpty()) {
currentNode = null;
return;
}
Node parent = depthChain.get(depthChain.size());
if (currentNode == parent.right || parent.right == null) {
currentNode = parent;
depthChain.remove(depthChain.size());
gotUpToTree();
} else {
currentNode = parent.right;
}
}
@Override
public void remove() {
throw new ConcurrentModificationException();
}
private void checkForComodification() {
if (expectedTreeSize != actualTreeSize()) {
throw new ConcurrentModificationException();
}
}
private int actualTreeSize() {
return analyzer.nodeSize(rootNode);
}
}
private class NodeAnalyzer {
private int size;
public NodeAnalyzer() {}
public int nodeSize(Node rootNode) {
size = 0;
goThroughNode(rootNode);
return size;
}
private void goThroughNode(Node node) {
if (node != null) {
size++;
goThroughNode(node.left);
goThroughNode(node.right);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment