Outline of Class 39: Introduction to Trees
Held: Monday, April 13, 1998
- Any questions on
- If you haven't done so already, please start reading chapter 10 of
- Today the brown-bag lunch series continues with Encapsulation and
Inheritance in C++.
- Many of the structures we've seen up to this point are linear
in that they are logically represented as a straight line of elements.
- By modifying one or more of the restrictions on our structures, we can
come up with some interesting nonlinear structures.
- Sometimes, modifications to one restriction may lead to modifications
to other restrictions.
- Consider lists. In one sense, lists are structures with the following
- Lists are collections of elements.
- There are two distinguished elements, first and last.
- Every element except for the last element has exactly one
- The last element has zero next elements.
- Every element except for the first element has exactly one
- The first element has zero previous elements.
- Suppose we allowed each element to have at least one
next element, but maintain the restriction on previous
- We'd also need to permit multiple "last" elements (o/w it's
useless to have multiple next elements).
- Trees are
- Collections of nodes (elements) with
- A designated root (first element)
- A number of leaves (last elements)
- In which every node except the leaves have one or more
children (next elements)
- The leaves have zero children.
- All nodes except the root have exactly one parent
- The root has no parents.
- Ordered Trees number the children of each node.
- What are the alternatives?
- Binary Trees are ordered trees in which nodes have at most two
children. They are among the most common types of trees.
- Trees are used for a wide variety of purposes in computing (and also
in life -- consider family trees), including
- building efficient ordered structures
- representing arithmetic expressions
- representing programs in an easily manipulable way
- representing relationships between classes in Java
- Traditionally, there is a value or contents
associated with each node in the tree.
- Depending on the usage, one may or may not choose to associate
values with all nodes.
- The most common alternative is to only store values at the leaves.
- While we have a high-level view of trees, it is also important to
ground that understanding in a particular interface that would
be provided by a tree structure.
- As with all of our other structures, there is some difference of opinion
as to what should be provided in an interface.
- Here is a very simple interface to a
TreeNode(Object value) -- Create a new tree.
void setSubtree(int childnum, TreeNode child) --
Set a subtree (child plus descendants) of the current tree.
TreeNode getSubtree(int childnum) -- Get one of the subtrees
of the current tree.
Object value() -- Get the value at the root of the tree.
- Note that there is no deletion operation. Why not?
- In this interface,
it's because there is no purpose to deletion -- we can simply
stop referring to a node.
- In more complex interfaces, it may be because it's not immediately
clear what deletion should do (except at the leaves).
- Should it delete a node and all descendants?
- Should it delete just the node and make its children the children
of its parent?
- Should it delete just the node and somehow manipulate its children?
- Note also that there is no parent operation in this interface.
Why not? Consider it analagous to our singly-linked lists in which there
was a next operation, but not a previous operation.
- What other design decisions do we have?
- Can we set a subtree to null?
- If our subtrees are ordered, and there is an nth subtree, do we
need to ensure that there is an n-1st subtree?
- Do we want to set the contents of a tree node?