package binarytrees; import java.util.LinkedList; import java.util.Queue; import java.util.Stack; /** * Given the root of a binary tree, print its pre-order, in-order and post-order * traversal to standard out. * * Signature of expected methods: * * public static void traversePreorder(TreeNode<?> rootNode) {...} * public static void traversePreorder(TreeNode<?> rootNode) {...} * public static void traversePreorder(TreeNode<?> rootNode) {...} * public static void traverseLevelorder(TreeNode<?> rootNode) {...} * * Given the root of a binary tree, print the level order traversal for a specific * level. * * Signature of expected method: * * public static void traverseLevelorder(TreeNode<?> rootNode, int level) {...} */ public class TreeNonRecursiveTraversals { public static void traversePreorder(TreeNode<?> rootNode) { if (rootNode == null) { return; } Stack<TreeNode<?>> stack = new Stack<TreeNode<?>>(); stack.push(rootNode); while (!stack.empty()) { TreeNode<?> current = stack.peek(); System.out.println(current); if (current.hasLeft()) { stack.push(current.getLeft()); } else { // Pop until we have a node with a right sub-tree. while (!stack.empty()) { current = stack.pop(); if (current.hasRight()) { stack.push(current.getRight()); break; } } } } } public static void traverseInorder(TreeNode<?> rootNode) { if (rootNode == null) { return; } Stack<TreeNode<?>> stack = new Stack<TreeNode<?>>(); stack.push(rootNode); while (!stack.empty()) { TreeNode<?> current = stack.peek(); if (current.hasLeft()) { stack.push(current.getLeft()); } else { // Pop and visit until we have a node with a right sub-tree. while (!stack.empty()) { current = stack.pop(); System.out.println(current); if (current.hasRight()) { stack.push(current.getRight()); break; } } } } } public static void traversePostorder(TreeNode<?> rootNode) { if (rootNode == null) { return; } Stack<TreeNode<?>> childStack = new Stack<TreeNode<?>>(); Stack<TreeNode<?>> rootStack = new Stack<TreeNode<?>>(); childStack.push(rootNode); while (!childStack.empty()) { TreeNode<?> current = childStack.peek(); if (!rootStack.empty() && current == rootStack.peek()) { // This means we have already traversed the left and // right sub-trees of current. System.out.println(current); childStack.pop(); rootStack.pop(); } else { rootStack.push(current); if (current.hasRight()) { childStack.push(current.getRight()); } if (current.hasLeft()) { childStack.push(current.getLeft()); } } } } // level (starting from 0) is the level that should be traversed. public static void traverseLevelorder(TreeNode<?> rootNode, int level) { if (level < 0) { throw new IllegalArgumentException(String.format( "level should be >= 0. You passed: %d.", level)); } if (rootNode == null) { return; } Queue<TreeNode<?>> q = new LinkedList<TreeNode<?>>(); q.add(rootNode); q.add(null); int levelCount = 0; while (!q.isEmpty()) { TreeNode<?> node = q.remove(); if (node == null) { if (levelCount == level) { break; } if (!q.isEmpty()) { q.add(null); levelCount++; } } else { if (levelCount == level) { System.out.println(node); } if (node.hasLeft()) { q.add(node.getLeft()); } if (node.hasRight()) { q.add(node.getRight()); } } } if (levelCount != level) { throw new IllegalArgumentException(String.format( "You passed an invalid level: %d.", level)); } } // traverse all levels in the binary tree. public static void traverseLevelOrder(TreeNode<?> rootNode) { if (rootNode == null) { return; } Queue<TreeNode<?>> q = new LinkedList<TreeNode<?>>(); q.add(rootNode); q.add(null); while (!q.isEmpty()) { TreeNode<?> node = q.remove(); System.out.println(node); if (node.hasLeft()) { q.add(node.getLeft()); } if (node.hasRight()) { q.add(node.getRight()); } } } }