Skip to content

Instantly share code, notes, and snippets.

@antonio081014
Created August 13, 2013 18:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save antonio081014/6224095 to your computer and use it in GitHub Desktop.
Save antonio081014/6224095 to your computer and use it in GitHub Desktop.
Yesterday(8/12/2013), I was asked to implement this problem Binary Tree Level-Order Traversal in a short time. For the first thought, it looks like an easy BFS problem, but quickly I realize a problem how can I track the level of the tree? Haha... At the end, I gave my solution, but the interviewee said my solution is most weird one he has ever …
/**
* This is a demo class in java <br />
* Implementing Binary Tree Traverse Level By Level with BFS and DFS. <br />
* All of the algorithm I implemented use O(N) time and space, N here represents the number of nodes in the tree.
*
*/
import java.util.LinkedList;
import java.util.Queue;
/**
* @author Antonio081014
* @since Aug 13, 2013, 9:22:40 AM
*/
public class BinaryTreeLevelTraversal {
public static void main(String[] args) {
BinaryTreeLevelTraversal main = new BinaryTreeLevelTraversal();
Node root = main.new Node("3");
root.left = main.new Node("9");
root.right = main.new Node("20");
root.right.left = main.new Node("15");
root.right.right = main.new Node("7");
main.printLevelOrder_Option4(root);
System.exit(0);
}
/**
* Tree node structure;
* */
class Node {
String value;
Node left;
Node right;
public Node(String v) {
value = v;
left = null;
right = null;
}
}
/**
* This is the answer I gave when I was in the interview.<br />
* Basically, track the number of children we counted, if all the children
* in that level is counted, then we print a newline and increase the tree
* level; The flaw of this algorithm is it can not take too many levels,
* since integer in java can't exceed 2^32; which means we maximumly will
* have 32 levels, even if we use long instead of int, this one is still not
* a good choice.
* */
private void printLevelOrder_Option0(Node root) {
if (root == null)
return;
Queue<Node> queue = new LinkedList<Node>();
int level = 1;
int count = 0;
queue.add(root);
while (!queue.isEmpty()) {
Node node = queue.poll();
if (count == 0)
System.out.print(node.value);
else
System.out.print(" " + node.value);
if (node.left != null)
queue.add(node.left);
if (node.right != null)
queue.add(node.right);
count += 2;
if (count == (int) Math.pow(2, level)) {
System.out.println();
level++;
count = 0;
}
}
}
/**
* Generally, this algorithm uses BFS, which involves two queues keep tracks
* of node in current level and nodes in next leve;<br />
* Basically,<br />
* 1, When a node is extracted, we print it, while adding its children to
* the next level if they are not null;<br />
* 2, When current level queue is empty, which means all of the current
* nodes are extracted and printed, also all the children of current level
* nodes are added to the next level queue. So we could just copy every
* single node in next level queue and add it to the current queue, and
* print the newline.
* */
private void printLevelOrder_Option1(Node root) {
if (root == null)
return;
Queue<Solution.Node> currentLevel = new LinkedList<Solution.Node>();
Queue<Solution.Node> nextLevel = new LinkedList<Solution.Node>();
currentLevel.add(root);
while (!currentLevel.isEmpty()) {
Solution.Node node = currentLevel.poll();
System.out.print(node.value + " ");
if (node.left != null)
nextLevel.add(node.left);
if (node.right != null)
nextLevel.add(node.right);
if (currentLevel.size() == 0) {
System.out.println();
while (!nextLevel.isEmpty()) {
currentLevel.add(nextLevel.poll());
}
}
}
}
/**
* For this algorithm, we use two counters to keep track of number of nodes
* in current level, and the number of nodes in next level; <br />
* This idea is very similar with printLevelOrder_Option1(Node root),
* however, it uses less memory and doesn't need to copy each node from one
* queue to another.
* */
private void printLevelOrder_Option2(Node root) {
if (root == null)
return;
Queue<Node> queue = new LinkedList<Node>();
int nodesInCurrentLevel = 0;
int nodesInNextLevel = 0;
queue.add(root);
nodesInCurrentLevel++;
while (!queue.isEmpty()) {
Node node = queue.poll();
System.out.print(" " + node.value);
nodesInCurrentLevel--;
if (node.left != null) {
queue.add(node.left);
nodesInNextLevel++;
}
if (node.right != null) {
queue.add(node.right);
nodesInNextLevel++;
}
if (nodesInCurrentLevel == 0) {
System.out.println();
nodesInCurrentLevel = nodesInNextLevel;
nodesInNextLevel = 0;
}
}
}
/**
* This algorithm uses a trick of BFS.<br />
* Since we are using BFS to traverse this binary tree level by level in a
* very nature way. We just add a newline node at the very beginning, then
* if this newline node is reached, that means all of nodes of current nodes
* has been visited, so we are going to move to the next level, then print
* the newline here.
*
* This trick uses the nature of BFS in binary, very smart. I think the
* interviewee was trying to ignite me to this solution. Somehow, I didn't
* get it. For this algorithm, user could replace this newline node with
* other flag node for other purposes.
* */
private void printLevelOrder_Option3(Node root) {
if (root == null)
return;
Queue<Node> queue = new LinkedList<Node>();
queue.add(new Node("\n"));
queue.add(root);
while (queue.size() > 1) {
Node node = queue.poll();
System.out.print(node.value + " ");
if (node.value.compareTo("\n") == 0) {
queue.add(node);
continue;
}
if (node.left != null)
queue.add(node.left);
if (node.right != null)
queue.add(node.right);
}
}
/**
* This algorithm uses DFS;<br />
* 1, Get the height from root tree node.<br />
* 2, For each level, print the nodes on that level with a newline.
*
* Although the DFS solution traverse the same node multiple times, it is
* not another order slower than the BFS solution. Here is the proof that
* the DFS solution above runs in O(N) time, where N is the number of nodes
* in the binary tree and we assume that the binary tree is balanced.
*
* We first compute the complexity of printLevel for the kth level:
*
* T(k) <br />
* = 2T(k-1) + c <br />
* = 2k-1 T(1) + c <br />
* = 2k-1 + c
*
* Assuming it’s a balanced binary tree, then it would have a total of lg N
* levels. Therefore, the complexity of printing all levels is:
*
* T(1) + T(2) + ... + T(lg N) = 1 + 2 + 22 + ... + 2lg N-1 + c = O(N)
* Finding the maximum height of the tree also takes O(N) time, therefore
* the overall complexity is still O(N).
* */
private void printLevelOrder_Option4(Node root) {
int height = treeLevel(root);
for (int i = 1; i <= height; i++) {
printLevel(root, i);
System.out.println();
}
}
/**
* Print the nodes on Level: level.
* */
private void printLevel(Node root, int level) {
if (root == null)
return;
if (level == 1) {
System.out.print(root.value + " ");
} else {
printLevel(root.left, level - 1);
printLevel(root.right, level - 1);
}
}
private int treeLevel(Node root) {
if (root == null)
return 0;
return 1 + Math.max(treeLevel(root.left), treeLevel(root.right));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment