1 / 48

Tree Data Structures

Tree Data Structures. Binary Tree Iterator. Similar idea to Linked Lists: Define a class that handles the traversal of the complete tree for us, allowing Start at root Movement to next node Visiting the data Arbitrary stopping (don’t have to completely traverse)

callahana
Télécharger la présentation

Tree Data Structures

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. Tree Data Structures

  2. Binary Tree Iterator • Similar idea to Linked Lists: Define a class that handles the traversal of the complete tree for us, allowing • Start at root • Movement to next node • Visiting the data • Arbitrary stopping (don’t have to completely traverse) • Implement iteratively (not recursively) – to allow for easy arbitrary stopping • Iterative needs to emulate recursive traversal – use a Stack?

  3. InorderIterator Class class InorderIterator { public: InorderIterator(BinaryTree& inputTree): tree(inputTree) { CurrentNode = tree.root;}; char* Next(); private: const BinaryTree& tree; Stack<BinaryTreeNode*> stack; BinaryTreeNode* currentNode; }

  4. InorderIterator Class char *InorderIterator::Next() { while (currentNode) { stack.Add(currentNode); currentNode = currentNode->leftChild; } if (! stack.isEmpty()) { currentNode = *(stack.Delete(currentNode)); char& temp = &(currentNode->data); currentNode = currentNode->rightChild; return &temp; } else return 0; // traversed whole tree }

  5. InorderIterator Validation + * E D * A / / / / C * * * * * * * * * A B + + + + + Stack: + Output: A

  6. InorderIterator Validation + * E D * / B / C * * * * * * A B Stack: + + + Output: / A [ETC…]

  7. InorderIterator Analysis • Computational complexity: • n nodes in tree • Every node is placed on stack once • As you pass it on your way down • Every node is removed from stack once • As you visit it on your way back up • O(n) computation • O(height) space -> bounded between: • O(log2n) on low end (complete, full) • O(n) on high end (skewed)

  8. Level-Order Traversal Rules: • Instead of going down to children first, go across to siblings • Visits all nodes on a given level in left-to-right order 1 2 3 4 5 6 7 1 3 2 4 5 6 7

  9. Level Order Traversal • Level order traversal also known as breadth-first traversal • Previous traversals made use of stack • Literally with iterative traversal • Figuratively with recursive traversal • To handle breadth-first search, need a queue in place of a stack

  10. Level Order Traversal • Add root node to queue • For a given node from the queue • Visit node • Add nodes left child to queue • Add nodes right child to queue

  11. Level Order Traversal void BinaryTree::LevelOrder() { Queue<BinaryTreeNode*> queue; BinaryTreeNode* currentNode = root; while (currentNode) { cout << currentNode->data; if (currentNode->leftChild) queue.Add(currentNode->leftChild); if (currentNode->rightChild) queue.Add(currentNode->rightChild; currentNode = *(queue.Delete(currentNode)); }

  12. LevelOrderValidation + * E D * / C A B Queue: * E E * D * D D / C Output: E + * *

  13. Binary Tree Operations • Extensions to Binary Tree class to support: • Copy Constructor (also very similar to = operation) • Equivalence (==) (only takes 1 more step to != implementation)

  14. Binary Tree Operations • Copy constructor: • Goal: Create a tree that mirrors the current tree • Do a tree traversal, creating new nodes in new tree as encounter first time in current tree.

  15. Binary Tree Copy Constructor BinaryTree::BinaryTree(const BinaryTree & input) { root = copy(input.root); } BinaryTreeNode* copy(BinaryTreeNode* current) { if (current) { BinaryTreeNode *temp = new BinaryTreeNode; temp->data = current->data; temp->leftChild = copy(current->leftChild); temp->rightChild = copy(current->rightChild); return temp; } else return 0; }

  16. Binary Tree Equivalence • Operator==: • Goal: Determine whether or not the two trees have the same data values and link orderings • Do a tree traversal, • Check whether or not nodes in the same place • Compare data values

  17. Binary Tree Equivalence bool operator==(const BinaryTree & tree1, const BinaryTree & tree2) { return equal(tree1.root, tree2.root); } bool equal(BinaryTreeNode* a, BinaryTreeNode* b) { if ((!a) && (!b)) return 1; // both null pointers if (a && b && (a->data == b->data) // same data && equal(a->leftChild,b->leftChild) // same left && equal(a->rightChild, b->rightChild) // same right return 1; return 0; }

  18. Binary Trees as Tools:Exploiting Traversal • Satisifiability Problem: • Given an arbitrary boolean expression, determine if there is a set of assignments to the variables so that the expression is true. (!x1 && x2) => x1 = false, x2 = true Satisfying assignment

  19. Satisfiability Rules • Expressions: • A variable is an expression • If x, y are expressions, so are • x && y, x || y, and !x • Normal order of evaluation: not > and > or • Parentheses can alter order of evaluation

  20. Satisfiability Problem • Represent expression in Binary Tree (x1 && !x2) || (!x1 && x3) || !x3 || Note: Terminals are all operands Internal nodes are operators. ! operator only has right child (unary) ! || x3 && && ! ! x1 x3 x2 x1

  21. Satisfiability Problem • Evaluate tree in postfix order (LRV) • Allows proper passing up of computed subexpression values • Computing left and right child (boolean values) before computing yourself, whose value is dependent on children. • Need to evaluate with all possible instantiations of true/false for terminal nodes

  22. Satisfiability Problem • Update node definition: • Data – holds type (and, or, not, true, false) • Value – holds answer computed from children class SatNode { friend class SatTree; private: SatNode *leftChild; TypesOfData data; bool value; SatNode* rightChild; }

  23. Satisfiability Problem • With each instantiation at the main level, will set node->data = initial true/false value for terminal nodes • Propagate up, without losing information on what types of operations are performed at higher levels

  24. Satisfiability Problem • Evaluation function: Rewrite of postorder traversal function void SatTree::PostOrderEval() { PostOrderEval(root); } void SatTree::PostOrderEval(SatNode *s) { if (node) { PostOrderEval(s->leftChild); PostOrderEval(s->rightChild); switch (s->data) { case LogicalNot: s-> value = !(s->rightChild->value); break; case LogicalAnd: s->value = s->leftChild->value && s->rightChild->value; break; case LogicalOr: s->value = s->leftChild->value || s->rightChild->value; break; case LogicalTrue: s->value = 1; break; case LogicalFalse: s-value = 0; break; } } }

  25. Review Questions A A B C B C D E D D C B A Inorder traversal? (LVR) D B E A C

  26. Review Questions A A B C B C D E D A B C D Preorder traversal? (VLR) A B D E C

  27. Review Questions A A B C B C D E D D C B A Postorder traversal? (LRV) D E B C A

  28. Review Questions • Write a function to compute the number of leaf nodes in a binary tree. int BinaryTree::CountTerminals() { return CountTerminals(root); } int BinaryTree::CountTerminals(BinaryTreeNode* node) { int left = 0; int right = 0; if ((node->leftChild == 0) && (node->rightChild == 0)) return 1; else { if (node->leftChild != 0) left = CountTerminals(node->leftChild); if (node->rightChild != 0) right = CountTerminals(node->rightChild); return left + right; } }

  29. Priority Queues • Standard queue definition: • Add to back, remove from front • Priority queue definition: • Add arbitrary priority to back, remove highest priority item • Very common! • OS scheduling • Packet switching

  30. Priority Queues – OS Job Scheduling CPU Next Job 5 3 7 12 15 turketwh ls turketwh g++ thomas df -k turketwh gnome root backup

  31. Priority Queues • Other Examples: • Selling service of a machine (renting carpet cleaners?) • Goal maximize number of users in a fixed time • Allow smallest homes (shortest rental time) to go first (a min priority queue) • Goal maximize money in a fixed time • Allows homeowners willing to pay the most to go first (a max priority queue)

  32. Priority Queue Interface Definition: template <class Type> class MaxPriorityQueue { public: virtual void Insert(const Element<Type> & toInsert) = 0; virtual Element<Type>* Delete (Element<Type> &) = 0; //(DeleteMax or DeleteMin) }

  33. Priority Queue Implementations • List implementations (on linked list): • Unordered list: • Insert – attach at front of list: O(1) • Delete – search entire list: O(N) • Sorted list: • Insert – find right place to insert: O(N) • Delete – pull off front: O(1)

  34. Heaps • Heaps are a guaranteed fast way to implement priority queues • Two Heap definitions: • A max tree is a tree in which the key value in each node is no smaller than the key values in its children (if any). A max heap is a complete binary tree that is also a max tree. • In a min tree, node keys are no larger than those for a node’s children. Min heap is a complete binary tree that is also min tree. • Root is largest item in max tree, smallest item in min tree

  35. Heap Examples: • Max Heaps: 9 9 14 6 6 7 3 3 12 5 10 8 6 5 Not A Max Heap! Complete binary? Yes Max Tree Property? Yes Complete binary? Yes Max Tree Property? Yes Complete binary? No Max Tree Property? Yes

  36. Heap Examples: • Min Heaps: 21 10 2 11 20 4 83 7 50 10 8 6 Not A Min Heap! Complete binary? Yes Min Tree Property? Yes Complete binary? Yes Min Tree Property? Yes Complete binary? Yes Min Tree Property? No

  37. Max Heap Operations • Minimal Interface: • Create an empty heap • Insert new element into heap • Delete largest element from the heap Same functionality as priority queue!

  38. Max Heap Definition: Variables • Since heaps are complete binary trees, simplest and densest implementation is via an array • Could also implement with left, right pointers. class MaxHeap { public: private: Element<Type> *heap; int currentSize; int maxSize; }

  39. Max Heap Definition: Methods class MaxHeap { public: MaxHeap(int size); bool isFull(); bool isEmpty(); void insert(Element<KeyType> toInsert); Element<KeyType>* delete(KeyType& toDelete); private: // see previous slide }

  40. Max Heap Implementation Constructor template<class KeyType> MaxHeap<KeyType>::MaxHeap(int size) { maxSize = size; currentSize = 0; heap = new Element<KeyType>[maxSize+1]; // heap[0] not used – simplifies binary tree // mapping } isFull, isEmpty() simple one-line conditional checks currentSize == maxSize or currentSize == 0

  41. Max Heap: Insertion To Insert First Rule: Insert in correct place to preserve complete binary tree Second Rule: Ensure Max Tree property 20 1 2 15 14 10 1

  42. Max Heap: Insertion To Insert First Rule: Insert in correct place to preserve complete binary tree Second Rule: Ensure Max Tree Property Repeatedly swap with parent if larger 20 5 2 15 14 10 20 5 5 15 14 If inserting 25 instead of 5, would have to move all the way to root 10 2

  43. Max Heap: Insertion template <class KeyType> Void MaxHeap<KeyType>::Insert(const Element<Type> & toInsert) { if (isFull()) return; currentSize = currentSize + 1; for (int i = currentSize; true; ) { if (i == 1) break; // if at root stop if (toInsert.key < heap[i/2].key) break; // if smaller than parent stop (preserve max tree property) heap[i] = heap[i/2]; // swap with parent i = i /2; // set parent position as potential insert // location } heap[i] = toInsert; // insert at appropriate place }

  44. Max Heap: Insertion Big Oh Analysis • Insertion: • Start Location: Leaf node (bottom of tree) • End Location: Root maximally, often less than root • Max distance between root and leaf node is log2(n+1) • O(1) at each node (simple compare) • O(log n) total time [better than sorted list implementation]

  45. Max Heap: Deletion 2 First Rule: Remove root node – Guaranteed largest Second Rule: Preserve complete binary tree property - Move rightmost, lowest into root position Third Rule: Preserve max tree property- Repeatedly push root down, swapping with larger of two children 20 5 5 15 15 14 14 10 10 2 15 5 14 2 10

  46. Max Heap: Deletion Implementation template <class KeyType> Element<KeyType>* MaxHeap<KeyType>::DeleteMax(Element <KeyType> & x) { if (isEmpty()) return 0; x = heap[1]; // grab root to return Element<KeyType> k = heap[currentSize]; // grab lowest rightmost item currentSize = currentSize – 1; for (int i= 1, j = 2; j <= currentSize; ) { if (j < currentSize) if (heap[j].key < heap[j+1].key) j++; // j points to the larger child now if (k.key >= heap[j].key) break; // in right place already heap[i] = heap[j]; // move child up if not in right place i = j; j *= 2; // move i,j down to continue swapping } heap[i] = k; // put in right place return &x; }

  47. Max Heap: Deletion Big O Analysis • 1 step to remove root node • 1 step to move bottom, right node to root • Potentially could move all the way down the tree in preserving max tree property • Max height = log2(n+1) • Each move is O(1) – a comparison • Overall work is O(log2n)

  48. Priority Queue Big Oh Comparisons: • Max Heap implementation of priority queue: • O(log n) insert O(log n) delete • Unsorted array • O(1) insert O(n) delete • Sorted array • O(n) insert O(1) delete

More Related