1 / 64

Trees

Trees. Chapter 11 Trees Overview Trees are a flexible data structure useful for solving a wide range of problems. Chapter Objectives. 1. Trees represent data in a hierarchical manner. 2. Binary search trees allow rapid retrieval by key, plus in-order processing.

posada
Download Presentation

Trees

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Trees

  2. Chapter 11 • Trees • Overview • Trees are a flexible data structure useful for solving a wide range of problems.

  3. Chapter Objectives • 1. Trees represent data in a hierarchical manner. • 2. Binary search trees allow rapid retrieval by key, plus in-order processing. • 3. Inheritance can be used to model “is-a” relationships and support code reuse.

  4. A Tree A B C D E F

  5. A binary tree A B C D E F G H I J K L M N

  6. Terminology • Node - tree element • Root - the node at the top • Parent/child nodes • Siblings - have the same parent • Levels - start with 0 • Depth - the level of a node • Internal nodes - nodes with children • Leaves - nodes without children • Height - Depth of the deepest leaf • Degree - number of child nodes

  7. Binary tree definition • A binary tree is either: • 1. an empty tree; or • 2. consists of a node, called a root, and two children, left and right, each of which are themselves binary trees.

  8. A Binary Tree

  9. Two distinct Binary Trees

  10. Expression trees • 3+7*2-1 • 3+(7*2)-1 grouping for * precedence • (3+(7*2))-1 left->right associative + vs. -

  11. Expression tree for 3 + 7 * 2 - 1 - + 1 3 X 7 2

  12. + 1 3 14 Expression tree after first subtree eliminated

  13. Expression tree after second subtree eliminated  17 1

  14. Final value of expression tree 16

  15. Binary Tree ADT • Characteristics • • A Binary Tree ADT T stores data of some type (btElementType • Operations • isEmpty • getData • insert • left • right • makeLeft • makeRight

  16. Binary tree interface file • template < class btElementType > • class BinaryTree { • public: • BinaryTree(); • bool isEmpty() const; • // Precondition: None. • // Postcondition: None. • // Returns: true if and only if T is an empty tree

  17. getData(), insert() • btElementType getData() const; // getData is an accessor • // Precondition: !this->isEmpty() • // Postcondition: None • // Returns: data associated with the root of the tree • void insert(const btElementType & d); • // Precondition: none • // Postconditions: this->getData() == d; !this->isEmpty()

  18. left() and right() • BinaryTree * left(); • // Precondition: !this->isEmpty() • // Postcondition: None • // Returns: (a pointer to) the left child of T • BinaryTree * right(); • // Precondition: !this->isEmpty() • // Postcondition: None • // Returns: (a pointer to) the right child of T

  19. makeLeft(), makeRight() • void makeLeft(BinaryTree * T1); • // Precondition: !this->isEmpty(); this->left()->isEmpty() • // Postcondition: this->left() == T1 • void makeRight(BinaryTree * T1); • // Precondition: !this->isEmpty(); this->right()->isEmpty() • // Postcondition: this->right() == T1

  20. Private section • private: • bool nullTree; • btElementType treeData; • BinaryTree * leftTree; • BinaryTree * rightTree; • }; nullTree { f/t} data left right

  21. Implementation file: constructor • template < class btElementType > • BinaryTree < btElementType > :: BinaryTree() • { • nullTree = true; • leftTree = 0; • rightTree = 0; • }

  22. isEmpty() • template < class btElementType > • bool • BinaryTree < btElementType > :: isEmpty() const • { • return nullTree; • }

  23. getData() • template < class btElementType > • btElementType • BinaryTree < btElementType > :: getData() const • { • assert(!isEmpty()); • return treeData; • }

  24. insert() • template < class btElementType > • void BinaryTree < btElementType > • :: insert(const btElementType & d) • { treeData = d; • if (nullTree) { • nullTree = false; • leftTree = new BinaryTree; • rightTree = new BinaryTree; • } }

  25. left() • template < class btElementType > • BinaryTree < btElementType > * • BinaryTree < btElementType > :: left() • { assert(!isEmpty()); • return leftTree; • }

  26. right() • template < class btElementType > • BinaryTree < btElementType > * • BinaryTree < btElementType > :: right() • { assert(!isEmpty()); • return rightTree; • }

  27. makeLeft() • template < class btElementType > • void BinaryTree < btElementType > • :: makeLeft(BinaryTree * T1) • { assert(!isEmpty()); • assert(left()->isEmpty()); • delete left(); // could be nullTree true, w/data • leftTree = T1; • }

  28. makeRight() • template < class btElementType > • void BinaryTree < btElementType > • :: makeRight(BinaryTree * T1) • { assert(!isEmpty()); • assert(right()->isEmpty()); • delete right(); • rightTree = T1; • }

  29. A bt6 B C bt3 bt5 D E F bt1 bt2 bt4 The operation of client code example

  30. Simple client for Binary Tree • int main() • { typedef BinaryTree < char > charTree; • typedef charTree * charTreePtr; • // Create left subtree (rooted at B) • // Create B's left subtree • charTreePtr bt1(new charTree); • bt1->insert('D'); • // Create B's right subtree • charTreePtr bt2(new charTree); • bt2->insert('E'); D bt1 E bt2

  31. Create tree • // Create node containing B, and link • // up to subtrees • charTreePtr bt3(new charTree); • bt3->insert('B'); • bt3->makeLeft(bt1); • bt3->makeRight(bt2); • // ** done creating left subtree bt3 B bt1 bt2 D E

  32. Create right subtree • // Create C's right subtree • charTreePtr bt4(new charTree); • bt4->insert('F'); • // Create node containing C, and link • // up its right subtree • charTreePtr bt5(new charTree); • bt5->insert('C'); • bt5->makeRight(bt4); • // ** done creating right subtree bt5 C F bt4

  33. Create the root of the tree • charTreePtr bt6(new charTree); • bt6->insert('A'); • bt6->makeLeft(bt3); • bt6->makeRight(bt5); • // print out the root • cout << "Root contains: " << bt6->getData() << endl;

  34. A bt6 B C bt3 bt5 D E F bt1 bt2 bt4 Final product

  35. Print left and right subtrees • // print out root of left subtree • cout << "Left subtree root: " << bt6->left()->getData() << endl; • // print out root of right subtree • cout << "Right subtree root: " << bt6->right()->getData() << endl;

  36. Print extreme child nodes • cout << "Leftmost child is: " << • bt6->left()->left()->getData() << endl; • cout << "Rightmost child is: " << • bt6->right()->right()->getData() << endl; • return 0; • }

  37. Expression trees • enum evalNodeType { evalOperator, evalOperand }; • enum evalOperatorType { add, subtract, multiply, divide };

  38. Class evalNode • class evalNode { • public: • evalNode(double d); • evalNode(evalOperatorType op); • evalNodeType getType() const; • double getOperand() const; • evalOperatorType getOperator() const; • private: • evalNodeType nodeType; • double nodeOperand; • evalOperatorType nodeOperator; • }; nodeType (op,opd) nodeOperand (1,2...) nodeOperator (+-*/)

  39. Typedefs (creates the tree) • typedef evalNode * evalNodePtr; // Pointer to an evalNode • // An evalTree is a BinaryTree of pointers to evalNodes • typedef BinaryTree < evalNodePtr > evalTree; • typedef evalTree * evalTreePtr; // Pointer to an evalTree • double evaluateTree(evalTreePtr t);

  40. Implementation file: polymorphism • evalNode::evalNode(double d) // creates operand node • { nodeType = evalOperand; • nodeOperand = d; • } • evalNode::evalNode(evalOperatorType op) • { nodeType = evalOperator; • nodeOperator = op; // creates operator node • }

  41. getType(), getOperand() • evalNodeType • evalNode::getType() const • { return nodeType; } // operator or operand • double • evalNode::getOperand() const • { assert(nodeType == evalOperand); • return nodeOperand; • }

  42. getOperator() • evalOperatorType • evalNode::getOperator() const • { • assert(nodeType == evalOperator); • return nodeOperator; • }

  43. evaluateTree() • double evaluateTree(evalTreePtr t) • { • assert(!t->isEmpty()); • evalNodePtr rootNodePtr = t->getData(); • if (rootNodePtr->getType() == evalOperand) • return rootNodePtr->getOperand();

  44. What kind of traversal is this? • else { • double left(evaluateTree(t->left())); • double right(evaluateTree(t->right())); • switch(rootNodePtr->getOperator()) { • case add: return left + right; • case subtract: return left - right; • case multiply: return left * right; • case divide: • assert(right); // avoids div by 0 • return left / right; • } // switch • } // else • } // evaluate tree

  45. Using the expression tree • int main() • { • evalTreePtr et1(new evalTree); • et1->insert(new evalNode(subtract)); • evalTreePtr et2(new evalTree); • et2->insert(new evalNode(add)); • evalTreePtr et3(new evalTree); • et3->insert(new evalNode(1.0)); - et1 + et2 1.0 et3

  46. et1->makeLeft(et2); et1->makeRight(et3); • evalTreePtr et4(new evalTree); • et4->insert(new evalNode(3.0)); • evalTreePtr et5(new evalTree); • et5->insert(new evalNode(multiply)); • et2->makeLeft(et4); et2->makeRight(et5); • evalTreePtr et6(new evalTree); • et6->insert(new evalNode(7.0)); - et1 et2 et3 + 1.0 et4 et5 3.0 * 7.0 et6

  47. evalTreePtr et7(new evalTree); • et7->insert(new evalNode(2.0)); • et5->makeLeft(et6); • et5->makeRight(et7); • cout << evaluateTree(et1) << endl; • return 0; • } - et1 et2 et3 + 1.0 et4 et5 3.0 * et7 et6 2.0 7.0

  48. Methods of tree traversal • Must visit every element once • Must no miss any • Three basic types • preorder • inorder • postorder

  49. Preorder traversal • if the tree is not empty • visit the root • preOrderTraverse(left child) • preOrderTraverse(right child)

  50. Inorder traversal • if the tree is not empty • inOrderTraverse(left child) • visit the root • inOrderTraverse(right child)

More Related