Trees CS212 & CS-240 D.J. Foreman What is a Tree • A tree is a finite set of one or more nodes such that: – There is a specially designated node called the root – The remaining nodes are partitioned into n>0 disjoint sets T1,..,Tn, where each of these sets is a tree. T1,..,Tn are the subtrees of the root. Examples - All are valid trees Tree Terms Root A A is the parent of B and C B height (h) C B and C are children of A B and C are siblings D interior nodes F E G H leaf nodes (exterior nodes) Definitions height - number of arcs in the longest path from root to farthest leaf parent - any connected node in the tree at the next higher level in the tree child - any connected node in the tree at the next lower level in the tree siblings - any nodes in the tree having a common parent order - the number of children in the node having the largest number of children binary tree - any order 2 tree binary search tree - any binary tree having the search tree property (more on this later) Nodal Structure Options If we know the maximum order that an arbitrary tree is supposed to be, we could allocate our data content and a child pointer for each possible child Ex suppose max. order = 5 each node would look like: Data child child child child child 1 2 3 4 5 If our tree has many nodes that have less than 5 children this representation could be very wasteful considering that each child pointer requires 4 bytes of storage. Is there a better, less wasteful representation? As it turns out, YES there is The lowly order 2 (binary) tree can be used to represent any order n tree. and we can make the statement that: for any general tree, there is an equivalent binary tree. To do this we must visualize an order 2 tree differently; instead of a collection of parents and children we view it as parent, leftmost child (ONLY) and that child’s siblings . This: Instead of this : A A B B C D C D Why do we want to do this? To explore this let us look at the problem of creating an algorithm for visiting every node in a tree in some predictable order. This problem is called Traversal and can be accomplished with the following the following algorithm. 1. start at the root and 2. follow all of the left links until you can’t go any farther 3. back-up one node and try going right, if you can, repeat steps 2 and 3, if you can’t, repeat step 3 Traversal Each node is visited 3 times Were we to print out the node data in the first visit to each node the printout would be : ABC Were we to printout the node data on the second visit to each node the printout would be: BAC A 3 1 2 1 3 B 2 3 1 C 2 Were we to printout the node data on the third visit to each node the printout would be: BCA These are called the: preorder, inorder and postorder traversals respectively Pre-order Traversal template <typename T> void preorder( tnode<T> *t) { if (t != NULL) { cout << t -> data << “ “; preorder(t -> left); preorder(t -> right); } } In-order Traversal template <typename T> void inorder( tnode<T> *t) { if (t != NULL) { inorder(t -> left); cout << t -> data << “ “; inorder(t -> right); } } Post-order Traversal template <typename T> void postorder( tnode<T> *t) { if (t != NULL) { postorder(t -> left); postorder(t -> right); cout << t -> data << “ “; } } Notice that... • the first node visited on the pre-order traversal is always the root • the left-most node in the tree is the first node on the inorder traversal • the last node visited on the inorder traversal is the rightmost node in the tree • the last node visited on the postorder traversal is the root • Knowing this and given any two traversal paths the tree can be constructed……. Armed with this information… • We can construct the tree that produced any pair of traversal paths