Presentation is loading. Please wait.

Presentation is loading. Please wait.

CSCS-200 Data Structures and Algorithms

Similar presentations


Presentation on theme: "CSCS-200 Data Structures and Algorithms"— Presentation transcript:

1 CSCS-200 Data Structures and Algorithms
Lecture

2 Degenerate Binary Search Tree
BST for 14, 15, 4, 9, 7, 18, 3, 5, 16, 20, 17 14 4 15 3 9 18 7 16 20 5 17

3 Degenerate Binary Search Tree
BST for 14 15 4 9 7 18 3 5 16 20 17

4 Degenerate Binary Search Tree
BST for 14 15 4 9 7 18 3 5 16 20 17 Linked List!

5 Balanced BST We should keep the tree balanced.
One idea would be to have the left and right subtrees have the same height

6 Balanced BST Does not force the tree to be shallow. 14 15 18 16 20 17
9 7 3 5 Does not force the tree to be shallow.

7 Balanced BST We could insist that every node must have left and right subtrees of same height. But this requires that the tree be a complete binary tree To do this, there must have (2d+1 – 1) data items, where d is the depth of the tree. This is too rigid a condition.

8 AVL Tree AVL (Adelson-Velskii and Landis) tree.
An AVL tree is identical to a BST except height of the left and right subtrees can differ by at most 1. height of an empty tree is defined to be (–1). Start of 20 (Nov 29)

9 AVL Tree An AVL Tree level 5 2 8 1 1 4 7 2 3 3

10 AVL Tree Not an AVL tree level 6 1 8 1 1 4 2 3 5 3

11 Balanced Binary Tree The height of a binary tree is the maximum level of its leaves (also called the depth). The balance of a node in a binary tree is defined as the height of its left subtree minus height of its right subtree. Here, for example, is a balanced tree. Each node has an indicated balance of 1, 0, or –1.

12 Balanced Binary Tree -1 1 1 -1 End of 19

13 Insertions and effect on balance
Balanced Binary Tree Insertions and effect on balance -1 1 1 -1 B B U1 U2 U3 U4 B B B B U5 U6 U7 U8 U9 U10 U11 U12

14 Balanced Binary Tree Tree becomes unbalanced only if the newly inserted node is a left descendant of a node that previously had a balance of 1 (U1 to U8), or is a descendant of a node that previously had a balance of –1 (U9 to U12)

15 Insertions and effect on balance
Balanced Binary Tree Insertions and effect on balance -1 1 1 -1 B B U1 U2 U3 U4 B B B B U5 U6 U7 U8 U9 U10 U11 U12

16 Balanced Binary Tree Consider the case of node that was previously 1
-1 1 1 -1 B B U1 U2 U3 U4 B B B B U5 U6 U7 U8 U9 U10 U11 U12

17 Inserting New Node in AVL Tree
1 B T1 T2 T3 1

18 Inserting New Node in AVL Tree
2 B 1 T1 T2 T3 1 2 new

19 Inserting New Node in AVL Tree
2 B A B 1 T1 T1 T2 T3 T2 1 T3 2 new new Inorder: T1 B T2 A T3 Inorder: T1 B T2 A T3

20 AVL Tree Building Example
Let us work through an example that inserts numbers in a balanced search tree. We will check the balance after each insert and rebalance if necessary using rotations.

21 AVL Tree Building Example
Insert(1) 1

22 AVL Tree Building Example
Insert(2) 1 2

23 AVL Tree Building Example
Insert(3) single left rotation 1 -2 2 3

24 AVL Tree Building Example
Insert(3) single left rotation 1 -2 2 3

25 AVL Tree Building Example
Insert(3) 2 1 3 End of lecture 20

26 AVL Tree Building Example
Insert(4) 2 1 3 4

27 AVL Tree Building Example
Insert(5) 2 1 3 -2 4 5

28 AVL Tree Building Example
Insert(5) 2 1 4 3 5

29 AVL Tree Building Example
Insert(6) 2 -2 1 4 3 5 6

30 AVL Tree Building Example
Insert(6) 4 2 5 1 3 6

31 AVL Tree Building Example
Insert(7) 4 2 5 -2 1 3 6 7

32 AVL Tree Building Example
Insert(7) 4 2 6 1 3 5 7

33 AVL Tree Building Example
Insert(16) 4 2 6 1 3 5 7 16

34 AVL Tree Building Example
Insert(15) 4 2 6 1 3 5 7 -2 16 15

35 AVL Tree Building Example
Insert(15) 4 2 6 1 3 5 16 -2 7 15

36 Cases for Rotation Single rotation does not seem to restore the balance. The problem is the node 15 is in an inner subtree that is too deep. Let us revisit the rotations.

37 Cases for Rotation Let us call the node that must be rebalanced .
Since any node has at most two children, and a height imbalance requires that ’s two sub trees differ by two (or –2), the violation will occur in four cases:

38 Cases for Rotation An insertion into left subtree of the left child of . An insertion into right subtree of the left child of . An insertion into left subtree of the right child of . An insertion into right subtree of the right child of .

39 Cases for Rotation The insertion occurs on the “outside” (i.e., left-left or right-right) in cases 1 and 4 Single rotation can fix the balance in cases 1 and 4. Insertion occurs on the “inside” in cases 2 and 3 which single rotation cannot fix.

40 Cases for Rotation Single right rotation to fix case 1.   k2 k1 k1
Z X Level n-2 Z X Y Y Level n-1 new Level n new

41 Cases for Rotation Single left rotation to fix case 4. k1 k2 X Y Z k2
Level n-2 X Y Level n-1 Level n

42 Cases for Rotation Single right rotation fails to fix case 2.   k2
Z Level n-2 X Y Y Z Level n-1 new new Level n

43 Cases for Rotation Y is non-empty because the new node was inserted in Y. Thus Y has a root and two subtrees. View the entire tree with four subtrees connected with 3 nodes. k2 k1 Z Y X End of lecture 21. Start of 22

44 Cases for Rotation Y is non-empty because the new node was inserted in Y. Thus Y has a root and two subtrees. View the entire tree with four subtrees connected with 3 nodes. k1 k3 D A B C k2

45 Cases for Rotation Exactly one of tree B or C is two levels deeper than D; we are not sure which one. Good thing: it does not matter. To rebalance, k3 cannot be left as the root. k3 k1 D k2 A 1 B C new 2 new’ New node inserted a either of the two spots

46 Cases for Rotation A rotation between k3 and k1 (k3 was k2 then) was shown to not work. The only alternative is to place k2 as the new root. This forces k1 to be k2‘s left child and k3 to be its right child. k3 k1 D k2 A 1 B C new 2 new’ New node inserted a either of the two spots

47 Cases for Rotation Left-right double rotation to fix case 2. k3 k2 k1
new B D C new’ k3 k2 k1 k3 Rotate left k1 D k2 A 1 B C new 2 New node inserted a either of the two spots new’

48 Cases for Rotation Left-right double rotation to fix case 2. k3 k2
Rotate right k2 k1 k3 D k1 A D C new’ B C A new B new new’

49 Cases for Rotation Right-left double rotation to fix case 3. k1 k1 k3
Rotate right k1 k3 k2 A A k2 k3 D B B C C D

50 Cases for Rotation Right-left double rotation to fix case 3. k1 k2 k2
Rotate left k2 k2 k1 k3 A B C k3 B A D C D

51 AVL Tree Building Example
Insert(15) 4 2 6 1 3 5 7 k1 16 k2 X (null) Y Z (null) 15

52 AVL Tree Building Example
Insert(15) right-left double rotation 4 2 6 k1 1 3 5 7 k3 16 k2 Rotate right 15

53 AVL Tree Building Example
Insert(15) right-left double rotation 4 2 6 k1 1 3 5 7 k2 Rotate left 15 k3 16

54 AVL Tree Building Example
Insert(15) right-left double rotation 4 2 6 15 k2 1 3 5 7 k1 16 k3

55 AVL Tree Building Example
Insert(14): right-left double rotation 4 k1 2 6 k3 1 3 5 15 k2 Rotate right 7 16 14

56 AVL Tree Building Example
Insert(14): right-left double rotation 4 k1 2 6 Rotate left k2 1 3 5 7 k3 15 14 16

57 AVL Tree Building Example
Insert(14): right-left double rotation 4 k2 7 2 6 k1 k3 15 1 3 5 14 16

58 AVL Tree Building Example
Insert(13): single rotation 4 Rotate left 2 7 1 3 6 15 5 14 16 13

59 AVL Tree Building Example
Insert(13): single rotation 1 2 3 4 5 16 15 7 6 14 13

60 C++ code for insert  TreeNode<int>*
avlInsert(TreeNode<int>* root, int info) { if( info < root->getInfo() ){ root->se tLeft(avlInsert(root->getLeft(), info)); int htdiff = height(root->getLeft()) – height(root->getRight()); if( htdiff == 2 ) if( info < root->getLeft()->getInfo() ) root = singleRightRotation( root ); else root = doubleLeftRightRotation( root ); }

61 C++ code for insert  TreeNode<int>*
avlInsert(TreeNode<int>* root, int info) { if( info < root->getInfo() ){ root->setLeft(avlInsert(root->getLeft(), info)); int htdiff = height(root->getLeft()) – height(root->getRight()); if( htdiff == 2 ) if( info < root->getLeft()->getInfo() ) root = singleRightRotation( root ); else root = doubleLeftRightRotation( root ); }

62 C++ code for insert  TreeNode<int>*
avlInsert(TreeNode<int>* root, int info) { if( info < root->getInfo() ){ root->setLeft(avlInsert(root->getLeft(), info)); int htdiff = height(root->getLeft()) – height(root->getRight()); if( htdiff == 2 ) if( info < root->getLeft()->getInfo() ) root = singleRightRotation( root ); else root = doubleLeftRightRotation( root ); } Root of left subtree may change

63 C++ code for insert  TreeNode<int>*
avlInsert(TreeNode<int>* root, int info) { if( info < root->getInfo() ){ root->setLeft(avlInsert(root->getLeft(), info)); int htdiff = height(root->getLeft()) – height(root->getRight()); if( htdiff == 2 ) if( info < root->getLeft()->getInfo() ) root = singleRightRotation( root ); else root = doubleLeftRightRotation( root ); }

64 C++ code for insert  TreeNode<int>*
avlInsert(TreeNode<int>* root, int info) { if( info < root->getInfo() ){ root->setLeft(avlInsert(root->getLeft(), info)); int htdiff = height(root->getLeft()) – height(root->getRight()); if( htdiff == 2 ) if( info < root->getLeft()->getInfo() ) root = singleRightRotation( root ); else root = doubleLeftRightRotation( root ); }

65 C++ code for insert  TreeNode<int>*
avlInsert(TreeNode<int>* root, int info) { if( info < root->getInfo() ){ root->setLeft(avlInsert(root->getLeft(), info)); int htdiff = height(root->getLeft()) – height(root->getRight()); if( htdiff == 2 ) if( info < root->getLeft()->getInfo() ) root = singleRightRotation( root ); else root = doubleLeftRightRotation( root ); } Outside case inside case

66 C++ code for insert  else if(info > root->getInfo() ) {
root->setRight(avlInsert(root->getRight(),info)); int htdiff = height(root->getRight()) – height(root->getLeft()); if( htdiff == 2 ) if( info > root->getRight()->getInfo() ) root = singleLeftRotation( root ); else root = doubleRightLeftRotation( root ); } // else a node with info is already in the tree. In // case, reset the height of this root node. int ht = Max(height(root->getLeft()), height(root->getRight())); root->setHeight( ht+1 ); // new height for root. return root;

67 C++ code for insert  else if(info > root->getInfo() ) {
root->setRight(avlInsert(root->getRight(),info)); int htdiff = height(root->getRight()) – height(root->getLeft()); if( htdiff == 2 ) if( info > root->getRight()->getInfo() ) root = singleLeftRotation( root ); else root = doubleRightLeftRotation( root ); } // else a node with info is already in the tree. In // case, reset the height of this root node. int ht = Max(height(root->getLeft()), height(root->getRight())); root->setHeight( ht+1 ); // new height for root. return root;

68 C++ code for insert  else if(info > root->getInfo() ) {
root->setRight(avlInsert(root->getRight(),info)); int htdiff = height(root->getRight()) – height(root->getLeft()); if( htdiff == 2 ) if( info > root->getRight()->getInfo() ) root = singleLeftRotation( root ); else root = doubleRightLeftRotation( root ); } // else a node with info is already in the tree. In // case, reset the height of this root node. int ht = Max(height(root->getLeft()), height(root->getRight())); root->setHeight( ht+1 ); // new height for root. return root;

69 C++ code for insert  else if(info > root->getInfo() ) {
root->setRight(avlInsert(root->getRight(),info)); int htdiff = height(root->getRight()) – height(root->getLeft()); if( htdiff == 2 ) if( info > root->getRight()->getInfo() ) root = singleLeftRotation( root ); else root = doubleRightLeftRotation( root ); } // else a node with info is already in the tree. In // case, reset the height of this root node. int ht = Max(height(root->getLeft()), height(root->getRight())); root->setHeight( ht+1 ); // new height for root. return root;

70 C++ code for insert  else if(info > root->getInfo() ) {
root->setRight(avlInsert(root->getRight(),info)); int htdiff = height(root->getRight()) – height(root->getLeft()); if( htdiff == 2 ) if( info > root->getRight()->getInfo() ) root = singleLeftRotation( root ); else root = doubleRightLeftRotation( root ); } // else a node with info is already in the tree. In // case, reset the height of this root node. int ht = Max(height(root->getLeft()), height(root->getRight())); root->setHeight( ht+1 ); // new height for root. return root;

71 C++ code for insert  else if(info > root->getInfo() ) {
root->setRight(avlInsert(root->getRight(),info)); int htdiff = height(root->getRight()) – height(root->getLeft()); if( htdiff == 2 ) if( info > root->getRight()->getInfo() ) root = singleLeftRotation( root ); else root = doubleRightLeftRotation( root ); } // else a node with info is already in the tree. In // case, reset the height of this root node. int ht = Max(height(root->getLeft()), height(root->getRight())); root->setHeight( ht+1 ); // new height for root. return root;

72 C++ code for insert  else if(info > root->getInfo() ) {
root->setRight(avlInsert(root->getRight(),info)); int htdiff = height(root->getRight()) – height(root->getLeft()); if( htdiff == 2 ) if( info > root->getRight()->getInfo() ) root = singleLeftRotation( root ); else root = doubleRightLeftRotation( root ); } // else a node with info is already in the tree. In // case, reset the height of this root node. int ht = Max(height(root->getLeft()), height(root->getRight())); root->setHeight( ht+1 ); // new height for root. return root; End of lecture 22.

73 singleRightRotation 
TreeNode<int>* singleRightRotation(TreeNode<int>* k2) { if( k2 == NULL ) return NULL; // k1 (first node in k2's left subtree) // will be the new root TreeNode<int>* k1 = k2->getLeft(); // Y moves from k1's right to k2's left k2->setLeft( k1->getRight() ); k1->setRight(k2); // reassign heights. First k2 int h = Max(height(k2->getLeft()), height(k2->getRight())); k2->setHeight( h+1 ); // k2 is now k1's right subtree h = Max( height(k1->getLeft()), k2->getHeight()); k1->setHeight( h+1 ); return k1; } k2 k1 Z Y X Start of lecture 23 k1 k2 Z Y X

74 singleRightRotation 
TreeNode<int>* singleRightRotation(TreeNode<int>* k2) { if( k2 == NULL ) return NULL; // k1 (first node in k2's left subtree) // will be the new root TreeNode<int>* k1 = k2->getLeft(); // Y moves from k1's right to k2's left k2->setLeft( k1->getRight() ); k1->setRight(k2); // reassign heights. First k2 int h = Max(height(k2->getLeft()), height(k2->getRight())); k2->setHeight( h+1 ); // k2 is now k1's right subtree h = Max( height(k1->getLeft()), k2->getHeight()); k1->setHeight( h+1 ); return k1; } k2 k1 Z Y X k1 k2 Z Y X

75 singleRightRotation 
TreeNode<int>* singleRightRotation(TreeNode<int>* k2) { if( k2 == NULL ) return NULL; // k1 (first node in k2's left subtree) // will be the new root TreeNode<int>* k1 = k2->getLeft(); // Y moves from k1's right to k2's left k2->setLeft( k1->getRight() ); k1->setRight(k2); // reassign heights. First k2 int h = Max(height(k2->getLeft()), height(k2->getRight())); k2->setHeight( h+1 ); // k2 is now k1's right subtree h = Max( height(k1->getLeft()), k2->getHeight()); k1->setHeight( h+1 ); return k1; } k2 k1 Z Y X k1 k2 Z Y X

76 singleRightRotation 
TreeNode<int>* singleRightRotation(TreeNode<int>* k2) { if( k2 == NULL ) return NULL; // k1 (first node in k2's left subtree) // will be the new root TreeNode<int>* k1 = k2->getLeft(); // Y moves from k1's right to k2's left k2->setLeft( k1->getRight() ); k1->setRight(k2); // reassign heights. First k2 int h = Max(height(k2->getLeft()), height(k2->getRight())); k2->setHeight( h+1 ); // k2 is now k1's right subtree h = Max( height(k1->getLeft()), k2->getHeight()); k1->setHeight( h+1 ); return k1; } k2 k1 Z Y X k1 k2 Z Y X

77 singleRightRotation 
TreeNode<int>* singleRightRotation(TreeNode<int>* k2) { if( k2 == NULL ) return NULL; // k1 (first node in k2's left subtree) // will be the new root TreeNode<int>* k1 = k2->getLeft(); // Y moves from k1's right to k2's left k2->setLeft( k1->getRight() ); k1->setRight(k2); // reassign heights. First k2 int h = Max(height(k2->getLeft()), height(k2->getRight())); k2->setHeight( h+1 ); // k2 is now k1's right subtree h = Max( height(k1->getLeft()), k2->getHeight()); k1->setHeight( h+1 ); return k1; } k2 k1 Z Y X k1 k2 Z Y X

78 singleRightRotation 
TreeNode<int>* singleRightRotation(TreeNode<int>* k2) { if( k2 == NULL ) return NULL; // k1 (first node in k2's left subtree) // will be the new root TreeNode<int>* k1 = k2->getLeft(); // Y moves from k1's right to k2's left k2->setLeft( k1->getRight() ); k1->setRight(k2); // reassign heights. First k2 int h = Max(height(k2->getLeft()), height(k2->getRight())); k2->setHeight( h+1 ); // k2 is now k1's right subtree h = Max( height(k1->getLeft()), k2->getHeight()); k1->setHeight( h+1 ); return k1; } k2 k1 Z Y X k1 k2 Z Y X

79 singleRightRotation 
TreeNode<int>* singleRightRotation(TreeNode<int>* k2) { if( k2 == NULL ) return NULL; // k1 (first node in k2's left subtree) // will be the new root TreeNode<int>* k1 = k2->getLeft(); // Y moves from k1's right to k2's left k2->setLeft( k1->getRight() ); k1->setRight(k2); // reassign heights. First k2 int h = Max(height(k2->getLeft()), height(k2->getRight())); k2->setHeight( h+1 ); // k2 is now k1's right subtree h = Max( height(k1->getLeft()), k2->getHeight()); k1->setHeight( h+1 ); return k1; } k2 k1 Z Y X k1 k2 Z Y X

80 height  int height( TreeNode<int>* node ) {
if( node != NULL ) return node->getHeight(); return -1; }

81 height  int height( TreeNode<int>* node ) {
if( node != NULL ) return node->getHeight(); return -1; }

82 singleLeftRotation TreeNode<int>* singleLeftRotation( TreeNode<int>* k1 ) { if( k1 == NULL ) return NULL; // k2 is now the new root TreeNode<int>* k2 = k1->getRight(); k1->setRight( k2->getLeft() ); // Y k2->setLeft( k1 ); // reassign heights. First k1 (demoted) int h = Max(height(k1->getLeft()), height(k1->getRight())); k1->setHeight( h+1 ); // k1 is now k2's left subtree h = Max( height(k2->getRight()), k1->getHeight()); k2->setHeight( h+1 ); return k2; } k1 k2 X Y Z k1 k2 X Y Z

83 singleLeftRotation TreeNode<int>* singleLeftRotation( TreeNode<int>* k1 ) { if( k1 == NULL ) return NULL; // k2 is now the new root TreeNode<int>* k2 = k1->getRight(); k1->setRight( k2->getLeft() ); // Y k2->setLeft( k1 ); // reassign heights. First k1 (demoted) int h = Max(height(k1->getLeft()), height(k1->getRight())); k1->setHeight( h+1 ); // k1 is now k2's left subtree h = Max( height(k2->getRight()), k1->getHeight()); k2->setHeight( h+1 ); return k2; } k1 k2 X Y Z k1 k2 X Y Z

84 singleLeftRotation TreeNode<int>* singleLeftRotation( TreeNode<int>* k1 ) { if( k1 == NULL ) return NULL; // k2 is now the new root TreeNode<int>* k2 = k1->getRight(); k1->setRight( k2->getLeft() ); // Y k2->setLeft( k1 ); // reassign heights. First k1 (demoted) int h = Max(height(k1->getLeft()), height(k1->getRight())); k1->setHeight( h+1 ); // k1 is now k2's left subtree h = Max( height(k2->getRight()), k1->getHeight()); k2->setHeight( h+1 ); return k2; } k1 k2 X Y Z k1 k2 X Y Z

85 singleLeftRotation TreeNode<int>* singleLeftRotation( TreeNode<int>* k1 ) { if( k1 == NULL ) return NULL; // k2 is now the new root TreeNode<int>* k2 = k1->getRight(); k1->setRight( k2->getLeft() ); // Y k2->setLeft( k1 ); // reassign heights. First k1 (demoted) int h = Max(height(k1->getLeft()), height(k1->getRight())); k1->setHeight( h+1 ); // k1 is now k2's left subtree h = Max( height(k2->getRight()), k1->getHeight()); k2->setHeight( h+1 ); return k2; } k1 k2 X Y Z k1 k2 X Y Z

86 singleLeftRotation TreeNode<int>* singleLeftRotation( TreeNode<int>* k1 ) { if( k1 == NULL ) return NULL; // k2 is now the new root TreeNode<int>* k2 = k1->getRight(); k1->setRight( k2->getLeft() ); // Y k2->setLeft( k1 ); // reassign heights. First k1 (demoted) int h = Max(height(k1->getLeft()), height(k1->getRight())); k1->setHeight( h+1 ); // k1 is now k2's left subtree h = Max( height(k2->getRight()), k1->getHeight()); k2->setHeight( h+1 ); return k2; } k1 k2 X Y Z k1 k2 X Y Z

87 singleLeftRotation TreeNode<int>* singleLeftRotation( TreeNode<int>* k1 ) { if( k1 == NULL ) return NULL; // k2 is now the new root TreeNode<int>* k2 = k1->getRight(); k1->setRight( k2->getLeft() ); // Y k2->setLeft( k1 ); // reassign heights. First k1 (demoted) int h = Max(height(k1->getLeft()), height(k1->getRight())); k1->setHeight( h+1 ); // k1 is now k2's left subtree h = Max( height(k2->getRight()), k1->getHeight()); k2->setHeight( h+1 ); return k2; } k1 k2 X Y Z k1 k2 X Y Z

88 doubleRightLeftRotation
TreeNode<int>* doubleRightLeftRotation(TreeNode<int>* k1) { if( k1 == NULL ) return NULL; // single right rotate with k3 (k1's right child) k1->setRight( singleRightRotation(k1->getRight())); // now single left rotate with k1 as the root return singleLeftRotation(k1); } k1 k3 D A B C k2

89 doubleRightLeftRotation
TreeNode<int>* doubleRightLeftRotation(TreeNode<int>* k1) { if( k1 == NULL ) return NULL; // single right rotate with k3 (k1's right child) k1->setRight( singleRightRotation(k1->getRight())); // now single left rotate with k1 as the root return singleLeftRotation(k1); } k1 k3 D A B C k2

90 doubleRightLeftRotation
TreeNode<int>* doubleRightLeftRotation(TreeNode<int>* k1) { if( k1 == NULL ) return NULL; // single right rotate with k3 (k1's right child) k1->setRight( singleRightRotation(k1->getRight())); // now single left rotate with k1 as the root return singleLeftRotation(k1); } k1 k2 k2 k1 k3 A B C k3 B A D C D

91 doubleRightLeftRotation
TreeNode<int>* doubleLeftRightRotation(TreeNode<int>* k3) { if( k3 == NULL ) return NULL; // single left rotate with k1 (k3's left child) k3->setLeft( singleLeftRotation(k3->getLeft())); // now single right rotate with k3 as the root return singleRightRotation(k3); } k1 k3 D A B C k2

92 doubleRightLeftRotation
TreeNode<int>* doubleLeftRightRotation(TreeNode<int>* k3) { if( k3 == NULL ) return NULL; // single left rotate with k1 (k3's left child) k3->setLeft( singleLeftRotation(k3->getLeft())); // now single right rotate with k3 as the root return singleRightRotation(k3); } k1 k3 D A B C k2

93 doubleRightLeftRotation
TreeNode<int>* doubleLeftRightRotation(TreeNode<int>* k3) { if( k3 == NULL ) return NULL; // single left rotate with k1 (k3's left child) k3->setLeft( singleLeftRotation(k3->getLeft())); // now single right rotate with k3 as the root return singleRightRotation(k3); } k3 k2 k2 k1 k3 D B C k1 C A D A B

94 Deletion in AVL Tree Delete is the inverse of insert: given a value X and an AVL tree T, delete the node containing X and rebalance the tree, if necessary. Turns out that deletion of a node is considerably more complex than insert

95 Deletion in AVL Tree Insertion in a height-balanced tree requires at most one single rotation or one double rotation. We can use rotations to restore the balance when we do a deletion. We may have to do a rotation at every level of the tree: log2N rotations in the worst case.

96 Deletion in AVL Tree Here is a tree that causes this worse case number of rotations when we delete A. At every node in N’s left subtree, the left subtree is one shorter than the right subtree. N F C I A D G K E H J L M

97 Deletion in AVL Tree Deleting A upsets balance at C. When rotate (D up, C down) to fix this N F C I A D G K E H J L M

98 Deletion in AVL Tree Deleting A upsets balance at C. When rotate (D up, C down) to fix this N F C I D G K E H J L M

99 Deletion in AVL Tree The whole of F’s left subtree gets shorter. We fix this by rotation about F-I: F down, I up. N F D I C E G K H J L M

100 Deletion in AVL Tree The whole of F’s left subtree gets shorter. We fix this by rotation about F-I: F down, I up. N F D I C E G K H J L M

101 Deletion in AVL Tree This could cause imbalance at N.
The rotations propagated to the root. N I F K D G J L C E H M

102 Deletion in AVL Tree Procedure
Delete the node as in binary search tree (BST). The node deleted will be either a leaf or have just one subtree. Since this is an AVL tree, if the deleted node has one subtree, that subtree contains only one node (why?) Traverse up the tree from the deleted node checking the balance of each node.

103 Deletion in AVL Tree There are 5 cases to consider.
Let us go through the cases graphically and determine what action to take. We will not develop the C++ code for deleteNode in AVL tree. This will be left as an exercise.

104 Deletion in AVL Tree Case 1a: the parent of the deleted node had a balance of 0 and the node was deleted in the parent’s left subtree. Delete on this side Start of lecture 24 Action: change the balance of the parent node and stop. No further effect on balance of any higher node.

105 Deletion in AVL Tree Here is why; the height of left tree does not change. 4 2 6 1 1 3 5 7 2

106 Deletion in AVL Tree Here is why; the height of left tree does not change. 4 4 2 6 1 2 6 1 3 5 7 2 3 5 7 remove(1)

107 Deletion in AVL Tree Case 1b: the parent of the deleted node had a balance of 0 and the node was deleted in the parent’s right subtree. Delete on this side Action: (same as 1a) change the balance of the parent node and stop. No further effect on balance of any higher node.

108 Deletion in AVL Tree Case 2a: the parent of the deleted node had a balance of 1 and the node was deleted in the parent’s left subtree. Delete on this side End of lecture 23. Action: change the balance of the parent node. May have caused imbalance in higher nodes so continue up the tree.

109 Deletion in AVL Tree Case 2b: the parent of the deleted node had a balance of -1 and the node was deleted in the parent’s right subtree. Delete on this side Action: same as 2a: change the balance of the parent node. May have caused imbalance in higher nodes so continue up the tree.

110 Deletion in AVL Tree Case 3a: the parent had balance of -1 and the node was deleted in the parent’s left subtree, right subtree was balanced.

111 Deletion in AVL Tree Case 3a: the parent had balance of -1 and the node was deleted in the parent’s left subtree, right subtree was balanced. Single rotate Action: perform single rotation, adjust balance. No effect on balance of higher nodes so stop here.

112 Deletion in AVL Tree Case 4a: parent had balance of -1 and the node was deleted in the parent’s left subtree, right subtree was unbalanced.

113 Deletion in AVL Tree Case 4a: parent had balance of -1 and the node was deleted in the parent’s left subtree, right subtree was unbalanced. double rotate Action: Double rotation at B. May have effected the balance of higher nodes, so continue up the tree.

114 Deletion in AVL Tree Case 5a: parent had balance of -1 and the node was deleted in the parent’s left subtree, right subtree was unbalanced.

115 Deletion in AVL Tree Case 5a: parent had balance of -1 and the node was deleted in the parent’s left subtree, right subtree was unbalanced. single rotate Action: Single rotation at B. May have effected the balance of higher nodes, so continue up the tree.

116 Other Uses of Binary Trees
Expression Trees

117 Expression Trees Expression trees, and the more general parse trees and abstract syntax trees are significant components of compilers. Let us consider the expression tree.

118 Expression Tree (a+b*c)+((d*e+f)*g) + + * a * + g b c * f d e

119 Parse Tree in Compiler A := A + B * C Expression grammar
<assign> <id> := <expr> A <expr> + <term> <term> <term> * <factor> <factor> <factor> <id> <id> <id> C A B Expression grammar <assign>  <id> := <expr> <id>  A | B | C <expr>  <expr> + <term> | <term> <term>  <term> * <factor> | <factor> <factor>  ( <expr> ) | <id>

120 Parse Tree for an SQL query
Consider querying a movie database Find the titles for movies with stars born in 1960 The database has tables StarsIn(title, year, starName) MovieStar(name, address, gender, birthdate) SELECT title FROM StarsIn, MovieStar WHERE starName = name AND birthdate LIKE ‘%1960’ ;

121 SQL Parse Tree < Query >
SELECT <SelList> FROM <FromList> WHERE <Condition> <Attribute> <RelName> , <FromList> AND title StarsIn <RelName> <Condition> <Condition> <Attribute> = <Attribute> <Attribute> LIKE <Pattern> starName name birthdate ‘%1960’ MovieStar

122 Compiler Optimization
Common subexpression: (f+d*e)+((d*e+f)*g) + + * f * + g d e * f d e

123 Compiler Optimization
(Common subexpression: (f+d*e)+((d*e+f)*g) + + * f End of lecture 24. * g d e Graph!


Download ppt "CSCS-200 Data Structures and Algorithms"

Similar presentations


Ads by Google