Last active
June 6, 2016 15:35
-
-
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
This file contains hidden or 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
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