Lecture No. Reference Variables One should be careful about transient objects that are stored by reference in data structures. Consider the following code that stores and retrieves objects in a queue.
Reference Variables void loadcustomer( Queue& q) { Customer c( irfan ); Customer c( sohail ; q.enqueue( c ); q.enqueue( c ); } Reference Variables void servicecustomer( Queue& q) { } Customer c = q.dequeue(); cout << c.getname() << endl; We got the reference but the object is gone! The objects were created on the call stack. They disappeared when the loadcustomer function returned.
Reference Variables void loadcustomer( Queue& q) { } Customer* c = new Customer( irfan ); Customer* c = new Customer( sohail ; q.enqueue( c ); // enqueue takes pointers q.enqueue( c ); The pointer variables c and c are on the call stack. They will go but their contents (addresses) are queued. The Customer objects are created in the heap. They will live until explicitly deleted. Memory Organization Process (browser) Process (word) Process (ourtest.exe) Process (dev-c++) Windows OS Code Static data Stack Heap
Reference Variables Call stack layout when q.enqueue(c) called in loadcustomer. elt 7 68 6 6... c c loadcustomer 6 (6) (elt) 6 enqueue sp stack grows downwards Reference Variables Heap layout during call to loadcustomer. heap grows upwards c 68 c sohail Customer( sohail ) -> c 6 irfan Customer( irfan ) -> c 6
Reference Variables void servicecustomer( Queue& q) { Customer* c = q.dequeue(); cout << c->getname() << endl; delete c; // the object in heap dies } Must use the c-> syntax because we get a pointer from the queue. The object is still alive because it was created in the heap. The const Keyword The const keyword is often used in function signatures. The actual meaning depends on where it occurs but it generally means something is to held constant. Here are some common uses.
The const Keyword Use : The const keyword appears before a function parameter. E.g., in a chess program: int movepiece(const Piece& currentpiece) The parameter must remain constant for the life of the function. If you try to change the value, e.g., parameter appears on the left hand side of an assignment, the compiler will generate and error. The const Keyword This also means that if the parameter is passed to another function, that function must not change it either. Use of const with reference parameters is very common. This is puzzling; why are we passing something by reference and then make it constant, i.e., don t change it? Doesn t passing by reference mean we want to change it? 6
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 and storing an entire copy of it. So, we make the original object available to the called function by using pass-by-reference. We also mark it constant so that the function will not alter it, even by mistake. The const Keyword Use : The const keyword appears at the end of class member s function signature: EType& findmin( ) const; Such a function cannot change or write to member variables of that class. This type of usage often appears in functions that are suppose to read and return member variables. 7
The const Keyword Use : The const keyword appears at the beginning of the return type in function signature: const EType& findmin( ) const; Means, whatever is returned is constant. The purpose is typically to protect a reference variable. This also avoids returning a copy of an object. Degenerate inary Search Tree ST for,,, 9, 7, 8,,, 6,, 7 9 8 7 6 7 8
Degenerate inary Search Tree ST for 7 9 6 7 8 7 9 6 7 8 Degenerate inary Search Tree ST for 7 9 6 7 8 7 9 Linked List! 6 7 8 9
alanced ST We should keep the tree balanced. One idea would be to have the left and right subtrees have the same height alanced ST 7 9 6 7 8 Does not force the tree to be shallow.
alanced ST We could insist that every node must have left and right subtrees of same height. ut this requires that the tree be a complete binary tree To do this, there must have ( d+ ) 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 ST except height of the left and right subtrees can differ by at most. height of an empty tree is defined to be ( ).
AVL Tree An AVL Tree level 8 7 AVL Tree Not an AVL tree 6 level 8
alanced inary 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,, or. alanced inary Tree - -
alanced inary Tree Insertions and effect on balance - - U U U U U U 6 U 7 U 8 U 9 U U U alanced inary Tree Tree becomes unbalanced only if the newly inserted node is a left descendant of a node that previously had a balance of (U to U 8 ), or is a descendant of a node that previously had a balance of (U 9 to U )
alanced inary Tree Insertions and effect on balance - - U U U U U U 6 U 7 U 8 U 9 U U U alanced inary Tree Consider the case of node that was previously - - U U U U U U 6 U 7 U 8 U 9 U U U
Inserting New Node in AVL Tree A T T T Inserting New Node in AVL Tree A T T T new 6
Inserting New Node in AVL Tree A A T T T T T T new new Inorder: T T A T Inorder: T T A T AVL Tree uilding 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. 7
AVL Tree uilding Example Insert() AVL Tree uilding Example Insert() 8
AVL Tree uilding Example Insert() single left rotation - AVL Tree uilding Example Insert() single left rotation - 9
AVL Tree uilding Example Insert() AVL Tree uilding Example Insert()
AVL Tree uilding Example Insert() - AVL Tree uilding Example Insert()
AVL Tree uilding Example Insert(6) - 6 AVL Tree uilding Example Insert(6) 6
AVL Tree uilding Example Insert(7) - 6 7 AVL Tree uilding Example Insert(7) 6 7 6
AVL Tree uilding Example Insert(6) 6 7 6 7 AVL Tree uilding Example Insert() 6 7-6 8
AVL Tree uilding Example Insert() 6 6-7 9 Cases for Rotation Single rotation does not seem to restore the balance. The problem is the node 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 subtrees differ by two (or ), 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. 6
Cases for Rotation The insertion occurs on the outside (i.e., left-left or rightright) in cases and Single rotation can fix the balance in cases and. Insertion occurs on the inside in cases and which single rotation cannot fix. Cases for Rotation Single right rotation to fix case. k k k Z Level n- X k X Y Level n- Y Z new Level n new 7
Cases for Rotation Single left rotation to fix case. k k X k Level n- k Y Level n- X Y Z Z Level n Cases for Rotation Single right rotation fails to fix case. k k k Z Level n- X k X Y Level n- Y Z new Level n new 6 8