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
  1. the data values at each node are all the same type
  2. the data values are comparable to one another
  3.  the values in the left subtree are all less than or equal to the node value
  4. 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?