Skip to content

Instantly share code, notes, and snippets.

@deyindra
Last active June 6, 2016 15:35
Show Gist options
  • Save deyindra/9eb693fb900ef9605b7802e146f98aad to your computer and use it in GitHub Desktop.
Save deyindra/9eb693fb900ef9605b7802e146f98aad to your computer and use it in GitHub Desktop.
In Order, Pre Order,Post Order,Level Order and Level Order till certain depth Iterators for Binary Tree
public abstract class AbstractTreeIterator<E> implements Iterator<E> {
protected AbstractTreeIterator(TreeNode<E> root){
assert(root!=null);
}
@Override
public void remove() {
throw new UnsupportedOperationException("remove is not supported");
}
}
public abstract class AbstractTreeDFSIterator<E> extends AbstractTreeIterator<E> {
protected final Stack<TreeNode<E>> stack;
protected AbstractTreeDFSIterator(TreeNode<E> root) {
super(root);
stack = new Stack<>();
}
@Override
public boolean hasNext() {
return !stack.isEmpty();
}
}
public abstract class AbstractTreeBFSIterator<E> extends AbstractTreeIterator<E> {
protected Queue<TreeNode<E>> queue;
public AbstractTreeBFSIterator(TreeNode<E> root) {
super(root);
this.queue = new LinkedList<>();
}
@Override
public boolean hasNext() {
return !queue.isEmpty();
}
}
public class InOrderTreeIterator<E> extends AbstractTreeDFSIterator<E> {
public InOrderTreeIterator(TreeNode<E> root) {
super(root);
for (TreeNode<E> current = root; current != null; current = current.getLeft()) {
this.stack.push(current);
}
}
@Override
public E next() {
if (!hasNext()) throw new NoSuchElementException("No more nodes remain to iterate");
TreeNode<E> current = stack.pop();
for (TreeNode<E> child = current.getRight(); child != null; child = child.getLeft()) {
stack.push(child);
}
return current.getData();
}
}
public class PostOrderTreeIterator<E> extends AbstractTreeDFSIterator<E> {
public PostOrderTreeIterator(TreeNode<E> root) {
super(root);
setNextNode(root);
}
private void setNextNode(TreeNode<E> current){
while (current != null) {
stack.push(current);
TreeNode<E> left = current.getLeft();
if (left != null) {
current = left;
} else {
current = current.getRight();
}
}
}
@Override
public E next() {
if (!hasNext()) {
throw new NoSuchElementException("All nodes have been visited!");
}
TreeNode<E> res = stack.pop();
if (!stack.isEmpty()) {
TreeNode<E> top = stack.peek();
if (res == top.getLeft()) {
setNextNode(top.getRight()); // find next leaf in right sub-tree
}
}
return res.getData();
}
}
public class PreOrderTreeIterator<E> extends AbstractTreeDFSIterator<E> {
public PreOrderTreeIterator(TreeNode<E> root) {
super(root);
stack.add(root);
}
@Override
public E next() {
if (!hasNext()) throw new NoSuchElementException("No more nodes remain to iterate");
final TreeNode<E> node = stack.pop();
TreeNode<E> left = node.getLeft();
TreeNode<E> right = node.getRight();
if (right != null) stack.push(right);
if (left != null) stack.push(left);
return node.getData();
}
}
public class LevelOrderIterator<E> extends AbstractTreeBFSIterator<E> {
public LevelOrderIterator(TreeNode<E> root) {
super(root);
this.queue.add(root);
}
@Override
public E next() {
if(!hasNext()) {
throw new NoSuchElementException("All nodes have been visited!");
}
TreeNode<E> current = queue.remove();
TreeNode<E> left = current.getLeft();
TreeNode<E> right = current.getRight();
if (left != null) queue.add(left);
if (right != null) queue.add(right);
return current.getData();
}
}
public class AdvancedLevelOrderIterator<E> extends LevelOrderIterator<E> {
private int nodesInCurrentLevel;
private int nodesInNextLevel;
private int currentLevel;
private final int maxlevel;
public AdvancedLevelOrderIterator(TreeNode<E> root, int maxLevel) {
super(root);
assert(maxLevel>=0);
this.maxlevel=maxLevel;
this.currentLevel=0;
this.nodesInCurrentLevel=1;
this.nodesInNextLevel=0;
}
@Override
public boolean hasNext() {
return super.hasNext() && currentLevel<=maxlevel;
}
@Override
public E next() {
if(!hasNext()) {
throw new NoSuchElementException("All nodes have been visited!");
}
TreeNode<E> current = queue.remove();
nodesInCurrentLevel--;
TreeNode<E> left = current.getLeft();
TreeNode<E> right = current.getRight();
if (left != null){
queue.add(left);
nodesInNextLevel++;
}
if (right != null){
queue.add(right);
nodesInNextLevel++;
}
if(nodesInCurrentLevel==0){
nodesInCurrentLevel = nodesInNextLevel;
nodesInNextLevel=0;
currentLevel++;
}
return current.getData();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment