1 / 90

CH10. SEARCH STRUCTURES

Learn about optimal binary search trees through a detailed algorithm using probabilities and identifiers to compute optimal cost and roots.

glorias
Download Presentation

CH10. SEARCH 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. CH10. SEARCH STRUCTURES

  2. 10.1 Optimal Binary Search Trees Figure 10.1: Binary search tree corresponding to a binary search on the file (do, if, while)

  3. 10.1 Optimal Binary Search Trees(Cont’) Figure 10.2: Two binary search trees

  4. 10.1 Optimal Binary Search Trees(Cont’) Figure 10.3: Extended binary trees corresponding to search trees of Figure 10.2

  5. 10.1 Optimal Binary Search Trees(Cont’) Figure 10.4: Binary search trees with three identifiers

  6. 10.1 Optimal Binary Search Trees(Cont’) Figure 10.5: An optimal binary search tree Tij

  7. 10.1 Optimal Binary Search Trees(Cont’) Figure 10.6: Computation of c04 and r04. The computation is carried out by Row from row 0 to row 4

  8. 10.1 Optimal Binary Search Trees(Cont’) Figure 10.7: Optimal binary search tree for Example 10.2

  9. 10.1 Optimal Binary Search Trees(Cont’) template <class KeyType> BST<KeyType>::obst(int *p, int *q, Element<KeyType> *a, int n) // Given n distinct identifiers a1<a2<···<an, and probabilities pj, 1≤j≤n, and // qi, 0≤i≤n this algorithm computes the cost cij of optimal binary search trees Tij // for identifiers ai+1,···,aj. It also computes rij, the root of Tij. Wij is the weight of Tij. { for(int i=0; i<n; i++) { w[i][i] = q[i]; r[i][i] = c[i][i] = 0; // initialize w[i][i+1] = q[i] + q[i+1] + p[i+1]; // optimal trees with one node r[i][i+1] = i + 1; c[i][i+1] = w[i][i+1]; } w[n][n] = q[n]; r[n][n] = c[n][n] = 0;

  10. 10.1 Optimal Binary Search Trees(Cont’) for(int m=2; m<=n; m++) // find optimal trees with m nodes for(i=0; i<=n-m; i++) { int j = i + m; w[i][j] = w[i][j-1] + p[j] + q[j]; int k = KnuthMin(I,j); // KnuthMin returns a value k in the range [r,[i, j-1], r[i+1, j]] // minimizing c[I, k-1] + c[k, j] c[i][j] = w[i][j] + c[i][k-1] + c[k][j]; // Eq.(10.3) r[i][j] = k; } } // end of obst Program 10.1 : Finding an optimal binary search tree

  11. 10.2 AVL Trees Figure 10.8: Binary search tree obtained for the months of the year

  12. 10.2 AVL Trees(Cont’) Figure 10.9: A balanced tree for the months of the year

  13. 10.2 AVL Trees(Cont’) Figure 10.10: Degenerate binary search tree

  14. 10.2 AVL Trees(Cont’)

  15. 10.2 AVL Trees(Cont’)

  16. 10.2 AVL Trees(Cont’)

  17. 10.2 AVL Trees(Cont’) Figure 10.11: Balanced trees obtained for the months of the year

  18. 10.2 AVL Trees(Cont’)

  19. 10.2 AVL Trees(Cont’)

  20. 10.2 AVL Trees(Cont’) Figure 10.12: Rebalancing rotations

  21. 10.2 AVL Trees(Cont’) template <class KeyType> Boolean AVL<KeyType>::Insert(const Element<KeyType>& x) // The identifier x is inserted into the AVL tree. AvlNode<KeyType> *a, *b, *c, *f, *p, *q, *y, *clchild, *crchild; Boolean Found, Unbalanced; int d; { if(!root) { // special case: empty tree y = new AvlNode<KeyType>; y -> data = x; root = y; root -> bf = 0; root -> LeftChild = root -> RightChild = 0; return TRUE; }

  22. 10.2 AVL Trees(Cont’) // phase 1: Locate insertion point for x. a keeps track of the most recent node with // balance factor ±1, and f is the parent of a. q follows p through the tree. f=0; a=p=root; q=0; Found=FALSE; while(p && !Found) { // search for insertion point for x if(p->bf) { a=p; f=q; } if(x.key < p->data.key) { q=p; p=p->LeftChild; } // take left branch else if(x.key > p->data.key) { q=p; p=p->RightChild; } else { y=p; Found=TRUE; } } // end of while

  23. 10.2 AVL Trees(Cont’) if(!Found) { // phase 1: Insert and rebalance. x is not in the tree and // may be inserted as the appropriate child of q. y = new AvlNode<KeyType>; y->data = x; y->LeftChild = y->RightChild = 0; y->bf = 0; if(x.key < q->data.key) q->LeftChild = y; // insert as left child else q->RightChild = y; // insert as right child // Adjust balance factors of nodes on path from a to q. Note that by the definition // of a, all nodes on this path must have balance factors of – and so will change to // ±1. d=+1 implies that x is inserted in the lift subtree of a. d = -1 implies // that x is inserted in the right subtree of a. if(x.key > a->data.key) { p = a->RightChild; b = p; d = -1; } else { p = a->LeftChild; b = p; d = 1; }

  24. 10.2 AVL Trees(Cont’) while(p!=y) if(x.key > p->data.key) { // height of right increases by 1 p->bf = -1; p = p->RightChild; } else { // height of left increases by 1 p->bf = 1; p = p->LeftChild; } Is tree unbalanced? Unbalanced = TRUE; if(!(a->bf) || !(a->bf + d)) { // tree still balanced a->bf += d; Unbalanced = FALSE; }

  25. 10.2 AVL Trees(Cont’) if(Unbalanced) { // tree unbalanced, determine rotation type if(d == 1) { // left imbalance if(b->bf == 1) { // rotation type LL a->LeftChild = b->RightCHild; b->RightChild = a; a->bf = 0; b->bf = 0; } else { // rotation type LR c = b->RightChild; b->RightChild = c->LeftChild; a->LeftChild = c->RightChild; c->LeftChild = b; c->RightChild = a; switch(c->bf) { case 1: // LR(b) a->bf = -1; b->bf = 0; break; case -1: // LR(c) b->bf = 1; a->bf = 0;

  26. 10.2 AVL Trees(Cont’) switch(c->bf) { case 1: // LR(b) a->bf = -1; b->bf = 0; break; case -1: // LR(c) b->bf = 1; a->bf = 0; break; case 0: // LR(a) b->bf = 0; a->bf = 0; break; } c->bf = 0; b = c; // b is the new root } // end of LR } // end of left imbalance else { // right imbalance: this is symmetric to left imbalance }

  27. 10.2 AVL Trees(Cont’) // Subtree with root b has been rebalanced and is the new subtree. if(!f) root = b; else if(a == f->LeftChild) f->LeftChild = b; else if(a == f->RightChild) f->RightChild = b; } // end of if Unbalanced return TRUE; } // end of if(!found) return FALSE; } // end of AVL::Insert Program 10.2 : Insertion into an AVL tree

  28. 10.2 AVL Trees(Cont’) Figure 10.13: Comparison of various structures

  29. 10.3 2-3 Trees 10.3.1 Definition and Properties • Definition A 2-3 tree is a search tree that either is empty or satisfies the following properties (1) Each internal node is a 2-node or a 3-node. A 2-node has one element; 3-node has two elements (2) Let LeftChild and MiddleChild denote the children of a 2-node. Let dataL be the element in this node, and let dataL.key be its key. All elements in the 2-3 subtree with root LeftChild have key less than dataL.key, whereas all elements in the 2-3 subtree with root MiddleChild have key greater than dataL.key

  30. 10.3 2-3 Trees(Cont’) (3) Let LeftChild, MiddleChild, and RightChild denote the children of 3-node. Let dataL and dataR be the two elements in this node. Then, dataL.key<dataR.Key; all keys in the 2-3 subtree with root LeftChild are less than dataL.key; all keys in the 2-3 subtree with root MiddleChild are less than dataR.key and greater than datL.key; and all keys in the 2-3 subtree with root RightChild are greater than dataR.key (4) All external nodes are at the same level

  31. 10.3 2-3 Trees(Cont’) Figure 10.14:Example of a 2-3 tree

  32. 10.3 2-3 Trees(Cont’) 10.3.2 Searching a 2-3 tree template <class KeyType> Two3Node<KeyType>* Two3<KeyType>::Search(const Element<KeyType>& x) //Search the 2-3 tree for an element x. If the element is not in the tree, then //return 0. Otherwise, return a pointer to the node that contains this element { for(Two3Node<KeyType> *p=root;p;) switch(p->compare(x)) { case 1: p=p->LeftChild; break; case 2: p=p->MiddleChild; break; case 3: p=p->RightChild; break; case 4: return p; //x is one of the keys in p } //end of switch and for } //end of Search Analysis : O(log n) Program 10.3:Searching a 2-3 tree

  33. 10.3 2-3 Trees(Cont’) 10.3.3 Insertion into a 2-3 tree Figure 10.15:Insertion into the 2-3 tree of Figure 10.14

  34. 10.3 2-3 Trees(Cont’) Figure 10.16:Insertion of 60 into the 2-3 tree of Figure 10.15(b)

  35. 10.3 2-3 Trees(Cont’) • Algorithm of the Insertion (1) void Two3::NewRoot(const Element& x, Two3Node *a) • be invoked when the root of the 2-3 tree is to change • The Single element x is inserted into the new root, while a is made its MiddleChild • The old root becomes the LeftChild of the new root

  36. 10.3 2-3 Trees(Cont’) (2) Two3Node* Two3::FindNode(const Element& x) • be a modified version of Two3::Search (Program 10.3) • searches a nonempty 2-3 tree for the presence of an element with key x.key • If this key is present, then it returns 0. Otherwise, it returns a pointer to the leaf node encountered in th search (3) void InsertionError() • When an attempt to insert an element whose key corresponds to that of an element already in the 2-3 tree is made, an insertion Error occurs • This function signals an error

  37. 10.3 2-3 Trees(Cont’) (3) void Two3Node::PutIn(const Element& x, TwoNode *a) • Be used to insert an element x into a node (this) that has exactly one element in it • The subtree a is to be placed immediately to the right of x • if x becomes dataL, then a becomes MiddleChild, and the previous values of dataL and MiddleChild move to dataR and Rightchild, respectively, • If x becomes dataR, then a becomes RightChild

  38. 10.3 2-3 Trees(Cont’) (5) Element& Two3::Split(Two3Node* p, Element& x, Two3Node *olda, Two3Node *a) • operates on a Two3Node (p) that initially contains two elements as follows • The newly created, empty node pointed at by a will contain the element with the largest key from among the two elements initially in p and the element x

  39. 10.3 2-3 Trees(Cont’) • Analysis : O(log n) Template <class KeyType> Boolean Two3<KeyType>::Insert(const Element<KeyType>& y) //Insert the element y into the 2-3 tree only if it does not already contain //an element with the same key. { Two3Node<KeyType> *p; Element<KeyType> x=y; if(x.key>=MAXKEY) return FALSE; //invalid key if(!root){ NewRoot(x, 0); return TRUE; } //empty 2-3 tree if(!(p=FindNode(x))) { InsertionError(); return FALSE; } //key already in 2-3 tree for(Two3Node<KeyType> *a=0; ; )

  40. 10.3 2-3 Trees(Cont’) if(p->dataR,key == MAXKEY) { //p is a 2-node p->PutIn(x, a); return TRUE; } else { //p is a 3-node Two3Node<KeyType> *olda=a; a=new(Two3Node<KeyType>); x=Split(p, x, olda, a); if(root==p) { //root has been split NewRoot(x, a); return TRUE; } else p=p->parent(); } //end of p is a 3-node and for loop } //end of Insert Program 10.4: Insertion into a 2-3 tree

  41. 10.3 2-3 Trees(Cont’) 10.3.4 Deletion from a 2-3 tree Figure 10.17: Deletion from a 2-3 tree(continued on next page)

  42. 10.3 2-3 Trees(Cont’) Figure 10.17: Deletion from a 2-3 tree

  43. 10.3 2-3 Trees(Cont’) • Algorithm of Deletion Step1 : Modify node p as necessary to reflect its status after the desired element has been deleted Step2 : for(;p has zero elements && p !=root; p=r) { let r be the parent of p, and let q be the left or right sibling of p (as appropriate) if(q is a 3-node) perform a rotation else perform a combine; } Step3 : If p has zero elements, then p must be the root. The left child of p becomes the new root, and node p is deleted Program 10.5: Step in deletion from a leaf of a 2-3 tree

  44. 10.4 2-3-4 Trees Figure 10.20: Example of a 2-3-4 tree

  45. 10.4 2-3-4 Trees(Cont’) Figure 10.21: Transformation when the 4-node is the root

  46. 10.4 2-3-4 Trees(Cont’) Figure 10.22: Transformation when the 4-node is the child of a 2-node

  47. 10.4 2-3-4 Trees(Cont’) Figure 10.23: Transformation when the 4-node is the lift child of a 3-node

  48. 10.4 2-3-4 Trees(Cont’) Figure 10.24: Transformation when the 4-node is the lift middle child of a 3-node

  49. 10.4 2-3-4 Trees(Cont’) template <class KeyType> Boolean Two34<KeyType>::Insert(const Element<KeyType>& y) // Insert element y into the 2-3-4 tree. { if(y.key >= MAXKEY) return FALSE; if(!root) { NewRoot(y); return TRUE; } // insertion into an empty 2-3-4 tree if(FourNode(root)) SplitRoot(); for(Two34Node<KeyType> *p = root, * q = 0 ; ;) // q is parent of p if(FourNode(p)) { if(NodeType(q) == TwoNode) SplitChildOf2(p, q); else SplitChildOf3(p, q); p = q; // back up to parent for next comparison }

  50. 10.4 2-3-4 Trees(Cont’) q = p; switch(p->compare(y)) { case equal: InsertionError(); return FALSE; // key is duplicated case leaf: p->PutIn(y); return TRUE; case lChild: p = p->LeftChild; break case lmChild: p = p->LeftMidChild; break; case rmChild: p = p->RightMidCHild; break; case rChild: p = p->RightChild; break; } // end of switch } // end of for } // end of Insert Program 10.9 : Insertion into a 2-3-4 tree

More Related