Traversals. When we iterate over a tree, we call this a “tree traversal”.
Depth First Traversals. We have three depth first traversals: Pre-order, in-order and post-order. In a pre-order traversal, we visit a node, then traverse its children. In an in-order traversal, we traverse the left child, visit a node, then traverse the right child. In a post-order traversal, we traverse both children before visiting. These are very natural to implement recursively. Pre-order and post-order generalize naturally to trees with arbtirary numbers of children. In-order only makes sense for binary trees.
Level Order Traversal. A level-order traversal visits every item at level 0, then level 1, then level 2, and so forth. One typical implementation for a level order traversal is an iterative-deepening strategy.
Visitor Pattern. To avoid rewriting tree traversal code for every single task, we can create traversal methods that take a function as an argument (wrapped up inside a Java object, as required by Java syntax).
Asymptotics of Traversals. Our depth-first traversals take linear time. Iterative deepening takes between N time and N^2 time. These facts are much less important than their derivations, which you should try to understand!
Range Finding and Pruning. Given a BST of items, we might be interested in finding all items that are greater than or equal to A but less than or equal to B. One approach would be to use the visitor pattern with any of our traversals, but this takes linear time at best. We can instead ignore searching subtrees that couldn’t possible contain the items of interest. For example if we are searching for items between 76 and 561, and we are currently at a node with label 76, we should not search the left subtree. We call this process pruning the search. With this technique, the runtime to complete the range finding process is $\Theta(R + \log N)$, where R is the number of matches. Range finding is the equivalent of finding all items on a line that are between two points.
The 2D Range Finding Problem. Suppose we have data that is ordered in two dimensions, e.g. the locations of Planets in space. Suppose further that we want to do the two dimensional analogue of our 1D range finding above: Specifically, we want to find everything on the plane that is inside a rectangle example. If we build a simple BST of objects ordered only on the X or Y position of each object, we cannot possibly prune the tree using the idea from above.
Quadtrees. To support pruning in 2 dimensions, we simply create a tree where each node has four children, corresponding to items to the upper left, upper right, bottom right, and bottom left, which we refer to as NW, NE, SE, and SW. Given such a structure, we can naturally extend our pruning algorithm.
- Question 1 from the Fall 2014 discussion worksheet.
- Question 4 from the Fall 2014 midterm.
Question 7 from the guerrilla section worksheet #2 from Spring 2015.
Prove that the runtime of range finding in a BST using pruning is $\Theta(R + \log N)$. Hint: Count the number of nodes that are examined if $R \lt \log N$.
For 2D range finding, why can’t we just build a BST ordered on some function of the X and Y coordinates and use the 1D range finding algorithm?