270 likes | 381 Views
Recursive Definition of Tree Structures. No rule is violated but we don’t like it. An empty collection is a tree A single node is a tree A node being linked to finite number of trees forms a tree. Is this definition good enough ?. 23. d4. 27. d4. d8. d1. d2. d3. d5. d6. d7.
E N D
Recursive Definition of Tree Structures No rule is violated but we don’t like it • An empty collection is a tree • A single node is a tree • A node being linked to finite number of trees forms a tree. Is this definition good enough ? 23 d4 27 d4 d8 d1 d2 d3 d5 d6 d7 ITK 279
Depict the Tree Structure in a better way height of d10 = 0 Terminologies come to play root d11 the links are directed height of d9 = 3 1 Ancestors d9 d10 2 leaf 1 Descendants Parent d8 depth of d8=2 2 Children d4 d3 d5 d6 d7 leaf leaf leaf leaf 3 d1 d2 Siblings leaf leaf ITK 279
More Terminologies • In-degree: the number of links pointing to a node (always 1 or 0); the root is the only node with in-degree 0. • 2. Out-degree: the number of link pointing out from a node; leaves are node with out-degree 0 • 3 . Degree of a tree: the maximum out-degree of nodes in the tree 23 d4 27 d8 d4 d3 d5 d6 d7 d1 d2 ITK 279
Recursive Definition of Tree Structures • Empty is a tree; the root is null • A single node is a tree; the node is the root of the tree. • A node points to finite number of roots of some trees form a tree; the node is the root of the tree 23 d4 27 d4 d8 d1 d2 d3 d5 d6 d7 ITK 279
Tree Implementation • Linked Lists data • data field • enough fields for pointers pointing the children Usually, using the number of degree of the tree. Fixed, if the degree is small, e.g., binary tree (degree is 2). ITK 279
Tree Implementation size = 2n - 1 n= height + 1 • Array height = 3 degree = 2 • the degree is small • the size (the number of node does not change very often) d1 0 2 1 d2 d3 5 d4 d5 d6 3 4 6 12 1st child (left-child) of i is 2*i+1; 2nd child (right-child) of i is 2*i+2. The parent of i is (i-1)/2 d7 What is the advantage and disadvantage of using array? ITK 279
A full-tree or complete tree is the perfect example for using array d1 d1 d2 d3 d2 d3 d7 d4 d5 d6 d7 d4 d5 d6 d8 d10 d8 d9 d10 d11 d12 d13 d14 d15 d9 complete tree full-tree ITK 279
A random binary tree: Randomly insert data into a binary tree 2 13 34 13 24 23 4 17 34 ITK 279
A data field • Two pointers to the left-child and right-child A Binary Tree Node in C++ template<typename T> class TreeNode { public: TreeNode(T t):data(t), left(NULL), right(NULL){}; T getdata() {return data;}; TreeNode<T> *left, *right; // The client program (list) // needs to maintain the link, so public. private: T data; // We don't want the data to be // changed directly. }; ITK 279
template<typename T> class RandomTree { public: RandomTree():root(NULL){}; // insert data into the tree; void insert(T data) { insert(data, root); } ; ......... // the Big tree yet to be implemented private: TreeNode<T> *root; // insert data into the sub-tree t; void insert(T data, TreeNode<T> * t); ....... }; ITK 279
enum Order {in, pre, post}; template<typename T> class RandomTree { public: RandomTree():root(NULL){}; void insert (T data); int howmany (T data); // Return how many such data in the tree void traversal (Order o); // Traveling through the tree; // the Big tree yet to be implemented private: TreeNode<T> *root; void insert(T data, TreeNode<T> * t); // insert data into the sub-tree t; void inorder(TreeNode<T> * t); // The following functions are helper; void postorder(TreeNode<T> * t); void preorder(TreeNode<T> * t); }; ITK 279
Insert a data into a random binary tree: data data data toss a coin head ITK 279
template<typename T> void RandomTree<T>::insert(T data) { if (root == NULL) root = new TreeNode<T>(data); else insert(data, root); } template<typename T> void RandomTree<T>::insert(T data, TreeNode<T> *t) { if (rand()%2) // toss a coin if (t->left == NULL) t->left = new TreeNode<T>(data); else insert(data, t->left); else if (t->right == NULL) t->right = new TreeNode<T>(data); else insert(data, t->right); } ITK 279
Tree traversal: preorder, inorder, postorder X L R X X L R L R inorder: L X R preorder: X L R postorder: L R X ITK 279
enum Order {in, pre, post}; template<typename T> void RandomTree<T>::traversal (Order o) { switch (o) { casein: inorder(root); break; casepre: preorder(root); break; casepost: postorder(root); break; } } template<typename T> void RandomTree<T>::inorder(TreeNode<T> * t) { if (t==NULL) return; inorder(t->left); cout << t->getdata() << ":"; inorder(t->right); } // (1) Travel to the left-child // (2) This is the way we visit the node // (3) Travel to the right-child ITK 279
template<typename T> void RandomTree<T>::preorder(TreeNode<T> * t) { if (t==NULL) return; cout << t->getdata() << ":"; preorder(t->left); preorder(t->right); } template<typename T> void RandomTree<T>::postorder(TreeNode<T> * t) { if (t==NULL) return; postorder(t->left); postorder(t->right); cout << t->getdata() << ":"; } // (1) This is the way we visit the node // (2) Travel to the left-child // (3) Travel to the right-child // (1 Travel to the left-child // (2) Travel to the right-child // (3) This is the way we visit the node ITK 279
Calculate the size of the tree, i.e., the number of nodes X root = NULL; 0 Ln Rn Ln + 1 + Rn ITK 279
template<typename T> class RandomTree { public: .... int size(); // Return the number of nodes in the tree private: .... void size(TreeNode<T> * t);// Return the number // of nodes in the sub-tree t; }; template<typename T> int RandomTree<T>::size () { return size(root); } template<typename T> int RandomTree<T>::size(TreeNode<T> * t) { if (t==NULL) return 0; return 1 + size(t->left) + size(t->right); } ITK 279
Count how many k’s in the tree X root = NULL; 0 Ln Rn if x = k, Ln + 1 + Rn ; otherwise, Ln + Rn ITK 279
template<typename T> class RandomTree { public: .... int count(T k); // Count the number of k in the tree private: .... void count(T K, TreeNode<T> * t);// Count the number // of k in the sub-tree t; }; template<typename T> int RandomTree<T>::count(T k) { return count(k, root); } template<typename T> int RandomTree<T>::count(Tk, TreeNode<T> * t) { if (t==NULL) return 0; return(t->getdata() == k ? 1 : 0) + count(k, t->left) + count(k, t->right); } ITK 279
Height of a Tree: The longest path from the root height = 4 template<typename T> class RandomTree { public: .... // return the height of the tree int height(); .... private: .... // return the height of the sub-tree t int height(TreeNode<T> * t); .... }; root d11 1 d10 d9 2 d8 3 Pop Quiz (10-3-2007): Implement the method height defined as above; (15 points, 10 minutes, open book and this slide) d4 d5 4 d1 d2 ITK 279
template<typename T> class RandomTree { public: .... // Return the height of the tree int height() {return height(root);}; private: .... void height(TreeNode<T> * t);// Return the height of // the sub-tree t; }; template<typename T> int RandomTree<T>::height(TreeNode<T> * t) { if (t==NULL) return -1; int l = height(t->left); int r = height(t->right); return 1 + (l > r ? l : r); } ITK 279
Without the Big Three void modify(RandomTree<int> T) { for (int i=0;i<5;i++) T.insert(rand()%20); } void main() { RandomTree<int> RT; for (int i=0;i<15;i++) RT.insert(rand()%20); int k = 15; RT.traversal(in); cout << "\nThere are " << RT.size() << " many nodes."; cout << "\nThere are " << RT.count(k) << " many " << k << “’s.\n\n"; modify(RT); RT.traversal(in); cout << "\nThere are " << RT.size() << " many nodes."; cout << "\nThere are " << RT.count(k) << " many " << k << “’s.\n\n"; } • Copy Constructor • Assignment operator = • Destructor 5:2:1:0:18:15:11:2:2:1:15:2:7:7:4: There are 15 many nodes. There are 2 many 15's. 2:5:2:1:3:0:18:15:11:6:2:2:1:15:2:7:7:4:15:6: There are 20 many nodes. There are 3 many 15's. Press any key to continue ITK 279
The Big Three template<typename T> class RandomTree { public: .... // The copy constructor RandomTree(const RandomeTree<T> & RT); .... private: .... // The helper for the copy constructor; TreeNode<T> * copy(TreeNode<T> *t); .... }; • Copy Constructor • Assignment operator = • Destructor d8 root root d8 d3 d5 d3 d5 d1 d2 d1 d2 ITK 279
Copy Constructor template<typename T> RandomTree<T>::RandomTree(const RandomTree<T> & RT) { root = copy(RT.root); } template<typename T> TreeNode<T> * RandomTree<T>::copy(TreeNode<T> *t) { if (t == NULL) return NULL; TreeNode<T> * newNode = new TreeNode<T>(t->getdata()); newNode->left = copy(t->left); newNode->right = copy(t->right); return newNode; } ITK 279
Big Three void modify(RandomTree<int> T) { for (int i=0;i<5;i++) T.insert(rand()%20); } void main() { RandomTree<int> RT; for (int i=0;i<15;i++) RT.insert(rand()%20); int k = 15; RT.traversal(in); cout << "\nThere are " << RT.size() << " many nodes."; cout << "\nThere are " << RT.count(k) << " many " << k << “’s.\n\n"; modify(RT); RT.traversal(in); cout << "\nThere are " << RT.size() << " many nodes."; cout << "\nThere are " << RT.count(k) << " many " << k << “’s.\n\n"; } • Copy Constructor • Assignment operator = • Destructor 5:2:1:0:18:15:11:2:2:1:15:2:7:7:4: There are 15 many nodes. There are 2 many 15's. 5:2:1:0:18:15:11:2:2:1:15:2:7:7:4: There are 15 many nodes. There are 2 many 15's. Press any key to continue ITK 279
Q: What is the benefit of using this random binary tree? (compare to Array and Single Linked lists) 2 Ok, The benefit is dismal! Why? 13 34 13 24 23 4 17 34 ITK 279