Comp 271 Week 9
Midterm: Tuesday
Trees
A linked list consists of nodes, where each node has one successor (or
none). A tree is a structure where the nodes can have more than one
"successor", or subnode. Trees are an effective way to represent
hierarchical data. One example is parse trees, that lay out the
hierarchical structure of mathematical formulas. Binary operators +, -,
*, / have two subexpressions, which become the subnodes.
Examples:
3+4
(3+4)*(9-2)
4*x+5*y
1+2+3+4 (=((1+2)+3)+4)
+
*
+
+
/
\
/
\
/
\
/ \
3
4
+
-
*
*
+ 4
/ \ /
\ / \
/ \ / \
3 4 9
2 4 x
5
y
+ 3
/ \
1 2
Note the convention that trees grow downwards, with the root at the top. In the 4*x+5*y example that some of the leaf nodes
are variables rather than numbers, and also that operator precedence
determines the grouping in the absence of parentheses. Also note here
that the leaf nodes contain numbers or variables, and the interior nodes, representing subexpressions, have operation symbols.
We saw another example of a tree structure in the analysis of the
coin-move game. Each node represents a position, and the subnodes
represent all the positions that are one move away from the parent. A branch
down through that tree represents a sequence of legal moves. For the
coin-move game, each node typically had 8 subnodes (four coins times
two directions each might move in); after 10 levels the tree would have
810 nodes, which is about a billion. That's way too many, so
the solution in the book used a trick to eliminate all positions that
had been encountered before; there are only 54 = 625
possible positions (each coin can be in one of 5 positions, and there
are 4 coins); this is a much more tractable number. (Note that we are
guaranteed that the shortest
solution will never use the same position twice; given any such
solution, we could cut out the part between the identical positions and
create a shorter solution.)
Binary search trees
A tree is binary if each node has at most two subnodes, which we generally denote the left child and the right child. A binary tree is ordered if
- the data values at each node are all the same type
- the data values are comparable to one another
- the values in the left subtree are all less than or equal to the node value
- the values in the right subtree are all greater than or equal to the node value.
Binary search trees are a form of ordered list,
although they do not support the full java.util.List interface. In
particular, there is usually no implementation of get(i), and certainly
no implementation of set() or any other mutator that would allow
elements to be out of order. However, iterators are possible, and ordered data is funamentally linear.
What binary search trees do is allow both lookup and in-order insertion
in time O(log n). By comparison, binary array search supports O(log n)
lookup, but insertion is in general O(n); linked lists allow O(1)
insertion but lookup is O(n).
The central idea of a tree structure is that each node contains a (possibly optional) data value, and then some subtrees. This boils down to a recursive definition: a tree is either null, or is a data value plus some (sub)trees.
Trees in BlueJ
TreeNode<T>
Note there are no constraints on T
TreeBuilder
Builds an Integer tree. Note that Integers can be compared. Note that
searching the tree is fundamentally recursive. Doing this
nonrecursively, in fact, is a bit of a pain.
Also note that insert is built upon search, which in turn was designed
to facilitate insert because of what it returns (ie if a search fails,
the node where the new value would be inserted is returned, not null!)
Demo 1: add 20 elements. Note that, most likely, the size is not 20! Why?
Demo 2: use the recursive print method. This is called tree traversal, or, more specifically, inorder tree traversal or infix tree traversal.
Tree<T extends Comparable<T>>
This is a full-fledged tree of any type that extends Comparable. Except
it's not finished! We have to change Integer to T. Is there anything
else?