Discussion 8: Reconstructing Binary Trees from Traversals
In lecture, we discussed three different traversal strategies for binary trees: pre-order, in-order and post-order traversals. These traversals provide different ways to “visit” all nodes in a tree and are fundamental for many algorithms, including expression evaluation, tree copying, and serialization. In this discussion, we’ll explore a challenging and interesting problem: Given the pre-order and in-order traversals of a binary tree, reconstruct the original tree.
Learning Outcomes
- Draw node diagrams to visualize tree structures.
- Implement recursive methods to build trees from pre-order and in-order traversal sequences.
- Analyze the correctness and complexity of recursive tree algorithms.
- Reason about the uniqueness of a tree given different types of traversals.
Reminder: Discussion Guidelines
The work that you complete in discussion serves as a formative assessment tool, meaning it offers the opportunity to assess your understanding of the material and for our course staff to get a “pulse” on how things are going so we can make adjustments in future classes. Your grade in discussion is based entirely on attendance and participation; if you show up and you are actively engaged with the activity (working on the activity on your computer, discussing the activity with your group, asking and answering questions, etc.) for the entire 50-minute section period, you will earn full credit. If you complete the activity early, helping other students is a great way to further your own understanding. You do not need to submit any of the work that you complete during discussion.
Since discussion activities are not graded for correctness, we do not place any restrictions on resources that you may use to complete them, which include notes, books, unrestricted conversations with other students, internet searches, and the use of large language models or other generative AI. We advise you to be pragmatic about your use of these resources and think critically about whether they are enhancing your learning. Discussion activities are intended to serve as “strength training” for programming tasks we will expect on assignments and exams (and that you will encounter in future courses and careers), and their main benefit comes from critically thinking to “puzzle” them out.
Working together in small groups is encouraged during discussion!
Integers.
Write out the pre-order, in-order and post-order traversals of this tree.
Pre-order:
In-order:
Post-order:
Use the ideas from the previous parts to draw the tree with the following traversals:
Pre-order: 3, 1, 4, 0, 2, 6, 5
In-order: 1, 4, 3, 2, 0, 5, 6
build() Method
build() helper method is the core of our code to reconstruct a binary tree from its pre-order and in-order traversals. Its purpose is simple yet powerful:
Given a segment of the pre-order array and the corresponding segment of the in-order array, construct the subtree represented by those segments and return its root node.
In essence, build() focuses on one part of the tree at a time — it identifies the current root, splits the arrays into left and right subtrees, and recursively constructs each subtree, ultimately connecting them into the complete binary tree.
|
|
|
|
Understanding the base cases:
- What should the method return if the current pre-order/in-order segments are empty (i.e., there is no subtree left to construct)? What condition will identify this case?
- What should the method return if the segment contains exactly one node? What condition will identify this case?
Finding the subtree segments:
Now, suppose we are not in one of the base cases.
- Write an expression with value equal to the root of the subtree returned by this method.
- How can we use the root to determine the sub-ranges of
inordercorresponding to its left/right subtrees? - How can we determine the sub-ranges of
preordercorresponding to its left/right subtrees?
Dividing the segments for recursion:
- After determining the correct sub-ranges for the left and right subtrees in both arrays, how can you recursively call
build()to construct each subtree? - How do we use the return values of these recursive calls to build the final tree that we must return?
TreeReconstruction class
BinaryTree and ImmutableBinaryTree classes are from the lecture code. You will only need to modify the TreeReconstruction class.
build() method.
build(), it’s time to complete the top-level method, the one that clients will actually call. This is the method that reconstructs the entire binary tree from its traversal arrays:
|
|
|
|
reconstructTree() method. This definition should consist of a single call to the build() helper method, with appropriately chosen parameters.
reconstructTree() method, expressed in terms of \(N=\) preorder.length ?