CSCS-200 Data Structures and Algorithms

Slides:



Advertisements
Similar presentations
AVL-Trees (Part 2) COMP171. AVL Trees / Slide 2 A warm-up exercise … * Create a BST from a sequence, n A, B, C, D, E, F, G, H * Create a AVL tree for.
Advertisements

AVL Trees1 Part-F2 AVL Trees v z. AVL Trees2 AVL Tree Definition (§ 9.2) AVL trees are balanced. An AVL Tree is a binary search tree such that.
1 AVL Trees. 2 AVL Tree AVL trees are balanced. An AVL Tree is a binary search tree such that for every internal node v of T, the heights of the children.
1 AVL Trees (10.2) CSE 2011 Winter April 2015.
AVL Trees COL 106 Amit Kumar Shweta Agrawal Slide Courtesy : Douglas Wilhelm Harder, MMath, UWaterloo
Trees Types and Operations
AVL Tree Smt Genap Outline AVL Tree ◦ Definition ◦ Properties ◦ Operations Smt Genap
AVL Trees CS II – Fall /8/2010. Announcements HW#2 is posted – Uses AVL Trees, so you have to implement an AVL Tree class. Most of the code is provided.
CS202 - Fundamental Structures of Computer Science II
AA Trees another alternative to AVL trees. Balanced Binary Search Trees A Binary Search Tree (BST) of N nodes is balanced if height is in O(log N) A balanced.
4.5 AVL Trees  A tree is said to be balanced if for each node, the number of nodes in the left subtree and the number of nodes in the right subtree differ.
AVL-Trees (Part 1) COMP171. AVL Trees / Slide 2 * Data, a set of elements * Data structure, a structured set of elements, linear, tree, graph, … * Linear:
CSC 2300 Data Structures & Algorithms February 13, 2007 Chapter 4. Trees.
Balanced Trees AVL Trees Red-Black Trees 2-3 Trees Trees.
1 Binary Trees Informal defn: each node has 0, 1, or 2 children Informal defn: each node has 0, 1, or 2 children Formal defn: a binary tree is a structure.
1 Trees 4: AVL Trees Section 4.4. Motivation When building a binary search tree, what type of trees would we like? Example: 3, 5, 8, 20, 18, 13, 22 2.
Data Structures AVL Trees.
Week 10 - Friday.  What did we talk about last time?  Graph representations  Adjacency matrix  Adjacency lists  Depth first search.
AVL Trees An AVL tree is a binary search tree with a balance condition. AVL is named for its inventors: Adel’son-Vel’skii and Landis AVL tree approximates.
AVL Trees AVL (Adel`son-Vel`skii and Landis) tree = – A BST – With the property: For every node, the heights of the left and right subtrees differ at most.
Lecture 15 Nov 3, 2013 Height-balanced BST Recall:
AA Trees.
File Organization and Processing Week 3
Data Structures – LECTURE Balanced trees
Search Trees.
Data Structures Lecture 22 Sohail Aslam.
Balancing Binary Search Trees
UNIT III TREES.
CSIT 402 Data Structures II
CS202 - Fundamental Structures of Computer Science II
CS202 - Fundamental Structures of Computer Science II
Chapter 26 AVL Trees Jung Soo (Sue) Lim Cal State LA.
CS 201 Data Structures and Algorithms
Chapter 29 AVL Trees.
Balanced Trees AVL : Adelson-Velskii and Landis(1962)
CSE373: Data Structures & Algorithms Lecture 7: AVL Trees
Week 11 - Friday CS221.
AVL Tree 27th Mar 2007.
AVL Trees "The voyage of discovery is not in seeking new landscapes but in having new eyes. " - Marcel Proust.
CSE373: Data Structures & Algorithms Lecture 7: AVL Trees
Chapter 22 : Binary Trees, AVL Trees, and Priority Queues
TCSS 342, Winter 2006 Lecture Notes
AVL Trees CENG 213 Data Structures.
AVL Trees: AVL Trees: Balanced binary search tree
CS202 - Fundamental Structures of Computer Science II
singleRightRotation 
Lecture No.16 Data Structures Dr. Sohail Aslam.
The const Keyword The answer is that, yes, we don’t want the function to change the parameter, but neither do we want to use up time and memory creating.
v z Chapter 10 AVL Trees Acknowledgement: These slides are adapted from slides provided with Data Structures and Algorithms in C++, Goodrich,
CSE 373: Data Structures and Algorithms
CSE 373: Data Structures and Algorithms
AVL Trees CSE 373 Data Structures.
CSE 373 Data Structures and Algorithms
Lecture No.20 Data Structures Dr. Sohail Aslam
Non-Linear Structures
CE 221 Data Structures and Algorithms
CS202 - Fundamental Structures of Computer Science II
Deletion in AVL Tree There are 5 cases to consider.
Data Structures Lecture 21 Sohail Aslam.
AVL-Trees (Part 1).
Lecture 10 Oct 1, 2012 Complete BST deletion Height-balanced BST
ITCS6114 Algorithms and Data Structures
Search Sorted Array: Binary Search Linked List: Linear Search
CSE 373 Data Structures Lecture 8
1 Lecture 13 CS2013.
CS 106B Lecture 20: Binary Search Trees Wednesday, May 17, 2017
CS202 - Fundamental Structures of Computer Science II
CS202 - Fundamental Structures of Computer Science II
Tree (new ADT) Terminology: A tree is a collection of elements (nodes)
AVL Trees: AVL Trees: Balanced binary search tree
Presentation transcript:

CSCS-200 Data Structures and Algorithms Lecture 21-22-23

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

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

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

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

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.

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.

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)

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

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

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.

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

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

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)

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

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

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

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

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

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.

AVL Tree Building Example Insert(1) 1

AVL Tree Building Example Insert(2) 1 2

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

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

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

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

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

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

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

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

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

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

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

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

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

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.

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:

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 .

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.

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

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

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

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

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

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

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

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’

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’

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

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

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

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

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

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

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

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

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

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

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

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 ); } 

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 ); } 

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 

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 ); } 

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 ); } 

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

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;

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; 

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; 

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; 

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; 

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; 

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. 

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

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

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

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

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

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 

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 

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

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

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

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

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

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

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 

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 

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

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

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

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

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

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

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

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.

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

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

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

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

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

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

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.

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.

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.

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

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)

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.

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.

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.

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.

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.

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.

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.

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.

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.

Other Uses of Binary Trees Expression Trees

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.

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

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>

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’ ;

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

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

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