1 Joe Meehean
A A B B D D I I C C E E X X
A A B B D D I I C C E E X X Terminology each circle is a node pointers are edges topmost node is the root bottom nodes are leaves no outgoing edges Every non-empty tree has one root one or more leaves
Node A is the parent of node B Node B is the child of node A The root has no parent All other nodes have exactly 1 parent A A B B
Not a tree D has 2 parents A A B B D D C C
Path is a sequence of connected nodes Length of a path is the number of edges in the path A to D is 2 C to F is 1 X is 0 A A B B D D C C F F X X Tree 1 Tree 2 Tree 3
Height of a tree: length of its longest path from root to leaf Ex: Height of 2 A A B B D D C C E E
Depth of a node: length of path from root Example A: 0 B: 1 E: 2 D: 2 C: 1 A A B B D D C C E E
Subtrees of a node are the nodes rooted at a node’s children A’s subtrees rooted at B rooted at C A A B B D D C C E E
Special Tree No node has more than 2 children can have 0,1, or 2 Each child is either “right” or “left” A A B B D D C C E E
A A B B D D C C E E X X Y Y Z Z S S T T
template class BinaryTreenode { private: D data_; BinaryTreenode * left_; BinaryTreenode * right_; public: BinaryTreenode(D d = D(), BinaryTreenode * left = NULL, BinaryTreenode * right = NULL); };
A A B B D D C C data: A right: left: data: C right: left: data: B right: left: data: D right: left:
Example Recursive definition of height for binary trees a tree with only a root (no children) has height 0 an non-empty tree has height 1 + max(height of left subtree, height of right subtree)
No fixed number of children per node can’t have single member variable per child use a list of children items in list will be Treenode *s template class Treenode { private: D data; list *> kids;
A A B B C C D D data:A kids:items: count: 3 data: B kids: data: C kids: data: D kids:
Alternative each node has a pointer to its first child each node has a pointer to its next sibling more basic linked list style template class Treenode { private: D data; Treenode * first_child_; Treenode * next_sibling_;
A A B B C C D D data:A first_: next_: data: B first_: next_: data: C first_: next_: data: D first_: next_:
19
Iterate through all nodes each node visited once, to… print all values see if a node has some property modify the node, etc… 4 common orders for visiting nodes preorder postorder in order (binary trees only) level order
Depth-first traversal Visit the root first Recursive definition visit the root do a preorder traversal of each subtree, left to right Ex: A B E D C F A A B B D D C C E E F F
void preorder(TreeNode* node){ if( node != null ){ //--visit node— // preorder the children list ::iterator iter; for( iter = node->kids.begin(); iter != node->kids.end(); iter++){ preorder(*iter); }
Depth-first traversal Visit the root last Recursive definition do a postorder traversal of each subtree, left to right visit the root Ex: E D B F C A A A B B D D C C E E F F
Depth-first traversal For binary trees only Visit root in between subtrees Recursive definition in-order traversal of left subtree visit the root in-order traversal of right subtree Ex: E B D A F C A A B B D D C C E E F F
Difference is in when root is visited Root first => preorder Root last => postorder Inbetween => in-order
Breadth-first traversal Visit all nodes at level 1 (depth 1) then level 2, level 3, etc… always left to right (or some order) Ex: A B C E D F A A B B D D C C E E F F
Use a queue instead of recursion (implicitly uses a stack) q.push(root); while( !q.empty() ){ //dequeue node n //visit n //enqueue all of n’s children(L to R) }
28
I laughed and he jumped she (ha!) ate allfive cakes Do the pre, post, in, and level order traversals
I laughed and he jumped she (ha!) ate allfive cakes Pre: I laughed and he jumped she (ha!) ate all 5 cakes In: and he laughed she jumped I all ate 5 (ha!) cakes Post: he and she jumped laughed all 5 ate cakes (ha!) I Level: I laughed (ha!) and jumped ate cakes he she all 5