Download presentation
Presentation is loading. Please wait.
1
Binary Trees our leafy, annoying friends
Annatala Wolf 2231 Lecture 5 1
2
Remember Trees? (from 2221) Graph: a set of vertices (or nodes) connected by edges Tree: an undirected, connected graph with no cycles Rooted Tree: a tree with one node designated “the root” Rooted trees are undirected, but often a direction toward or away from the root is useful to imagine. Rooted trees are usually ordered (you can tell the difference between each child). Our XMLTree component is a rooted, ordered tree. 2
3
Visualizing Rooted Trees
When we draw rooted trees, we often use the following common conventions: Draw the root of the tree at the top Draw vertices horizontally level based on how many edges they are from the root If the tree is ordered, draw the outgoing (child) edges from left to right in that order. <0, 1, 2…> (if ordered by number) 3
4
Rooted Tree Terminology
Size: total number of nodes. Height: total number of levels (max distance from the root). Leaves are nodes without children. Nodes with children are called internal nodes. 4
5
Binary Trees A binary tree is a rooted tree where every node has at most two children. Binary trees are also often ordered. This means there is a distinct left child and right child. The Tree of Harmony is not a binary tree. 5
6
The Order Zero (“Empty”) Tree
In mathematics, the order zero graph is a graph with no vertices (or edges) at all. The order zero graph is usually not considered a graph, and almost never considered a tree. However, if we consider the order zero graph to be a tree (the order zero tree, or empty tree), we can use it to simplify the recursive structure of a binary tree. This is why we define the height of a tree as the total number of levels rather than distance from the root (our definition adds 1 to the common). 6
7
(subtrees might still be empty)
Recursive Structure Think of each binary tree as either being empty, or consisting of a root node, a left subtree, and a right subtree. (subtrees might still be empty) ø OR empty tree (0 nodes, 0 edges) non-empty tree 7
8
What We Gain We no longer have special cases for nodes based on whether they have left, right, both, or neither child. All nodes now have exactly two subtrees. A A B ø B C D C D ø ø E ø E ø ø 8
9
this will be part of the recursive base case.
Thinking Recursively By defining binary trees recursively, it’s much easier to work with them. The only special case we have to handle is the empty tree case, so the interface can be much simpler. Our only special case. Often (but not always), this will be part of the recursive base case. ø empty tree (0 nodes, 0 edges) non-empty tree 9
10
BinaryTree Intuitively, a BinaryTree is an Iterable collection with one “base” item (the root), and the rest of the items partitioned to the left or right of the root. You can only access the root, or break the tree into the root and its two subtrees. Mathematically, BinaryTree is an ordered binary tree of T. default value: the empty tree 10
11
Why not direct access? Like XMLTree, BinaryTree does not have a method for breadth-first traversal. When you work with an arbitrary tree, you’ll need to use a depth-first approach. Unlike XMLTree, BinaryTree also requires you to take the tree apart in order to drill down into its subtrees. (This necessitates recursion!) The reasoning behind this is that we don’t need this functionality for what we’ll be using the component. This makes its interface much simpler to work with. 11
12
Note: the abstract class BinaryTreeSecondary
Interfaces and Classes Note: the abstract class BinaryTreeSecondary is not shown here.
13
BinaryTreeKernel Methods
assemble(root, left, right) requires: true replaces this T disassemble(root, left, right) requires: this clears this int size( ) requires: true 13
14
BinaryTree Methods T root() T replaceRoot(newRoot) int height( )
requires: this T replaceRoot(newRoot) int height( ) requires: true inOrderAssemble(…) (not needed right now) 14
15
Using BinaryTree Anything you do using BinaryTree will need to be recursive. The only way to work with BinaryTree is to handle one node of the tree at a time. If you ever disassemble a subtree, you’re probably doing it wrong. You must rely upon recursion to do the work for you at lower levels! Binary tree has a recursive structure, and only recursion will correctly exploit it. 15
16
Preconditions for BinaryTree
The only precondition for BinaryTree is: You cannot disassemble(…) or mess with the (non-existent) root of the empty tree. Fortunately, the empty tree is easy to recognize. It is the only tree that has a size (and a height) of zero. Frequently, the empty tree will be the base case for recursion—but not always! Some methods might have “|tree| > 0” as a precondition, so the base case may need to be something different. 16
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.