Tree Traversal

The function is handed a log book from the parameter. Now it needs to travel down this tree and log its visits in a top-down (root to leaf) fashion.

Without using recursion or corecursion specifically, one may traverse a tree by starting at the root node, placing its child nodes in a data structure, then iterating by removing node after node from the data structure while placing each removed node's children back into that data structure.[b] If the data structure is a stack (LIFO), this yields depth-first traversal, and if the data structure is a queue (FIFO), this yields breadth-first traversal. -- Wikipedia

Preorder Traversal (LC.144)

Given a binary tree, return the preorder traversal of its nodes' values.

Analysis

Traverse - traverse the entire tree and add nodes in a certain order. preorder will add root.val in the beginning, inorder will add root.val in the middle, and postorder will add root.val in the end.

D&C - the boss breaks down his task into the same subproblems and assign his employees to do it then report to the boss when they are done. *One major difference b/w traverse and D&C is that D&C must have a return value (the report to the boss).

Iteratively - use an explicit stack and be careful with the ordering. Iterative DFS has the opposite ordering as the recursive DFS.

Traverse

public ArrayList<Integer> preorderTraversal(TreeNode root) {
    ArrayList<Integer> visitLog = new ArrayList<>();
    preOrderHelper(root, visitLog);
    return visitLog;
}

private void preOrderHelper(TreeNode root, ArrayList<Integer> visitLog) {
    // base case
    if (root == null) {
        return;
    }
    // log
    visitLog.add(root.val);
    // visit
    preOrderHelper(root.left, visitLog);
    preOrderHelper(root.right, visitLog);
}

D&C

Iteratively

Dump children nodes to a data structure. This is like a regular DFS (w/ opposite ordering). Pretty easy to understand.

N-ary Tree Preorder Traversal (LI.1526)

Inorder Traversal (LC.94)

Given a binary tree, return the inorder traversal of its nodes' values.

Traverse

D&C

Trace this one. It makes sense to go down all the way to the left, print and backtrack, print then go right, then backtrack.

Iteratively

The else statement kinda works as an iterative backtracking. We want to stop the search when the current pointer is at bottom right of the binary tree and nothing to backtrack to.

It can be hard to implement the iterative version of in-order traversal after pre-order traversal. There are 2 distinctions to help clarifying the approach.

  1. When to backtrack?

    1. Should be coupled with stack frame being removed

  2. Where does the last iteration stop?

    1. Same place with each subtree (the traversal is recursive in nature)

Going through the tree will help visualize the algorithmic movement. But going through a base case will help implement the stop condition correctly.

Postorder Traversal (LC.145)

Given a binary tree, return the postorder traversal of its nodes' values.

Traverse

D&C

Iteratively

the key is to understand the use of lastVisit and peek

  • peek is for going right first before root

  • what about lastVisit? make sure you don't step down on the right path again

Time & Space Complexity

duh we need to visit all the nodes so time will be O(V). The stack space is proportional to the height of the tree. Note: the height of tree is not necessarily logn, the worst case can be n, a linear tree. So we have O(h) where a balanced tree can be O(logn) and a linear tree can be O(n).

References

Wikipedia Tree Traversal

ʕ; •`ᴥ•´ʔ

Last updated