CSE 143 Linear vs. Branching • Our data structures so far are linear – Have a beginning and an end Trees – Everything falls in order between the ends – Arrays, linked lists, queues, stacks, priority queues, etc. • Everyday life has branching structures, too. [Chapter 10] – Family genealogy – Biology: phylum/genus/species – Company organization chart – Table of contents 3/25/2001 3/25/2001 W-1 W-2 Branching Structures in CS Board of Directors • Trees are a common branching structure in CS • We’ve seen already: CEO – Class hierarchies – Call graphs – Recursive function traces Engineering Manufacturing Sales • PS: Some of these won’t quite be “trees” under our official definition Domestic Foreign – The org chart was not a tree (go back later and see why) Sales Operations Research Development Overseas Foreign Manufacturing Sales 3/25/2001 3/25/2001 W-3 W-4 A Tree What’s in a Node? • Answer: anything you want! root • Could have a tree of ints, tree of students, animals, appointments, etc. nodes (vertices) a – All nodes will be of the same (base) type edges b j • For simplicity, we often label the nodes with a c g k m single letter or an integer d e f h i l leaves 3/25/2001 3/25/2001 W-5 W-6 W
Formal Textbook Definition Tree Terminology • A general tree T is either empty, or is a set of • Empty tree : tree with no nodes nodes such that T is partitioned into disjoint • Child of a node u subsets: – Any node reachable from u by 1 edge pointing away from u 1. A subset with a single node r (called the root) – Nodes can have zero, one, or more children 2. Subsets that are themselves general trees (these are • Leaf: a node with no children called the subtrees of T). • If b is a child of a , then a is the parent of b • Notes: – All nodes except root have exactly one parent – This definition is recursive! – Root has no parent – The nodes are not defined. They can be anything, and still satisfy the definition. 3/25/2001 3/25/2001 W-7 W-8 Descendants Ancestors j • Descendant of a node (recursive definition) • Ancestor of a node – 1. P is a descendant of P for any node P – Definition: If D is a descendant of A, then A is k m an ancestor of D – 2. If C is a child of P, and P is a descendant of A, l then C is a descendant of A • Example: j , k , and l are ancestors of l • Puzzle: neither rule states explicitly that if C j is a child of P, C is also a descendant of P. k m Is it? Do we need another rule? l • Example: – what are the descendents of j ? – Of what is l a descendant? 3/25/2001 3/25/2001 W-9 W-10 Subtree Terminology Height and Level • Subtree • Level or depth (recursive definition) a 1 – Any node of a tree, with all of its descendants – Level of root node is 1 b j 2 – Puzzle: is b-c a subtree of the tree starting at a? Is it a tree? – Level of any node other than root is one greater than level c g k m 3 of its parent y • Height a – Height of a tree is maximum of all depths of its leaves b j – Height of empty tree is defined to be 0 • Warning: Definitions vary c g k m – Some textbooks define level of the root node as 0, • so root node height would be 0, empty tree height would be -1 3/25/2001 3/25/2001 W-11 W-12 W
Binary Trees Importance of Binary Trees • A binary tree is a tree each of whose nodes has • Binary trees are widely used in Computer Science no more than two children • Much easier to represent (find a good data – The two children are called the left child and right structure for) than general trees child • Much easier to manipulate (write and implement • The trees which start with these children are called the left algorithms) than general trees subtree and the right subtree – See textbook for formal recursive definition • Turns out that any general tree can be represented using a binary tree. a Left child Right child – Won’t discuss in this course b i c f j 3/25/2001 3/25/2001 d e g h k W-13 W-14 Binary Tree as an ADT Implementing A Binary Tree • Textbook lists 18 operations! • Using an array – constructors and destructors – Efficient – bool isEmpty – See textbook 452-453 for details • won’t discuss further in this course – return/set root data – Drawbacks: not flexible in terms of size; wastes space – attach left or right child nodes if tree is unbalanced – attach left or right subtrees • Using dynamic memory – detach left or right subtrees – Similar to linked list implementation – return a copy of left or right subtree – Two pointers, one each for left and right subtrees – traversals (more late) – See textbook 455ff for details • Will use in this course 3/25/2001 3/25/2001 W-15 W-16 Binary Tree Data Structure Example: Counting Nodes • Base case: Empty tree has zero nodes root • Binary tree node (for a tree of ints): struct BTreeNode { • Recursive case: Nonempty tree has one node int item; item (the root) plus nodes in left subtree plus nodes BTreeNode *left; left right in right subtree BTreeNode *right; }; // return # of nodes in tree with given root • Keep a root pointer to the root node int CountNodes (BTreeNode *root) { – Analogous to head pointer for a linked list if ( root == NULL ) – Empty tree has a NULL root return 0; // base case • will usually omit NULL pointers when drawing pictures else • This example shows node for a tree of ints return 1 + CountNodes (root->left) + CountNodes (root->right); – but “item” could be any type, even a class object } 3/25/2001 3/25/2001 W-17 W-18 W
Binary Trees and Recursion Finding the Height struct BTreeNode { • Base case: Empty tree has height 0 int item; • Recursive case: Nonempty tree has height 1 more BTreeNode *left; BTreeNode *right; than maximum height of left and right subtrees }; // returns height of tree with given root • Note the recursive data structure int Height (BTreeNode *root) { • Algorithms often are recursive as well if ( root == NULL ) • Don’t fight it! Recursion is going to be the natural return 0; way to express the algorithms else return 1 + max( Height (root->left), – Challenge: code CountNodes without using recursion Height (root->right)); } 3/25/2001 3/25/2001 W-19 W-20 Analyses Exercises • What is running time of these algorithms? Do try these at home! – Time to execute for one node: O(1) • 1. Find the sum of all the values (items) in a binary tree of integers – Number of recursive calls: O(N) • 2. Find the smallest value in a B.T. of integers • N is the number of nodes in tree • 3. (A little harder) Count the number of leaf nodes • There’s no way to miss any node in a B.T. • There’s no way to get to any node twice – Each node is called from its parent, and a node has only • 4. (A little harder) Find the average of all the one parent values in a B.T. (one approach: think in terms of a “kickoff” function) 3/25/2001 3/25/2001 W-21 W-22 Recursive Tree Searching Complexity of Find • How to tell if a data item is in a binary tree? • What is the running time of this algorithm? – Worst case: Has to visit every node in the tree, O(N) // true iff “item appears in tree with given root” • Can we do better? bool find(BTreeNode *root, int item) { if ( root == NULL ) – Answer: not without changing the data structure return false; – We will shortly look at a binary search tree else if ( root->data == item ) • Items will have an order, which will make searching more return true; efficient. else return ( find(root->left, item) || – But first we take up another topic: traversals. find(root->right, item) ); } 3/25/2001 3/25/2001 W-23 W-24 W
Tree Traversal Pre and Post Order Traversals • Functions to count nodes, find height, sum, etc. • Preorder traversal: systematically “visit” each node – “Visit” the (current) node first • This is called a traversal • i.e., do what ever processing is to be done – We also used this word in connection with lists. – Then, (recursively) do preorder traversal on its • Traversal is a common pattern in many children, left to right algorithms • Postorder traversal: – The processing done during the “visit” varies with the – First, (recursively) do postorder traversals of algorithm children, left to right • What order should nodes be visited in? – Visit the node itself last – Many are possible – Three have been singled out as particularly useful: • PS: These algorithms make sense for non- preorder, postorder, and inorder binary trees, too. 3/25/2001 3/25/2001 W-25 W-26 Inorder Example of Tree Traversal • Unlike pre- and post-, makes sense only for binary Assume this question: in 9 trees what order are the nodes 5 12 visited, if we start the • Inorder traversal: process at the root? 2 7 – (Recursively) do inorder traversal of left child 10 13 – Then visit the (current) node 1 4 6 8 l1 – Then (recursively) do inorder traversal of right child Preorder: Inorder: Postorder: 3/25/2001 3/25/2001 W-27 W-28 More Practice Two Traversals for Printing void printInOrder (BTreeNode* t) { void printPreOrder (BTreeNode* t) { What about this tree? if (t != NULL) { if (t != NULL) { Preorder: printInOrder (t->left); cout << t->data << “ “; 6 cout << t->data << “ “; printPreOrder (t->left); printInOrder (t->right); printPreOrder (t->right); 3 8 Inorder: } } 1 4 7 10 } } 2 5 Postorder: l3 11 12 3/25/2001 3/25/2001 W-29 W-30 W
Recommend
More recommend