Last active
September 26, 2016 08:13
-
-
Save programmerr47/1775c4c4c9876bea7b8777d77e16cd10 to your computer and use it in GitHub Desktop.
Iterator for "going" through tree by using DFS.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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