cse 373 avl trees
play

CSE 373: AVL trees Question: is this also an AVL tree? 2 5 6 10 - PDF document

CSE 373: AVL trees Question: is this also an AVL tree? 2 5 6 10 9 8 12 11 13 14 5 AVL tree invariants review 6 4 2 1 4 3 5 8 7 12 10 9 11 13 3 7 Michael Lee Question: is this a valid AVL tree? Friday, Jan 19, 2018 1


  1. CSE 373: AVL trees Question: is this also an AVL tree? 2 5 6 10 9 8 12 11 13 14 5 AVL tree invariants review 6 4 2 1 4 3 5 8 7 12 10 9 11 13 3 7 Michael Lee Question: is this a valid AVL tree? Friday, Jan 19, 2018 1 Warmup Warmup: Discuss with your neighbor. 2 AVL Trees: Invariants Core idea: add extra invariant to BSTs that enforce balance. AVL Tree Invariants An AVL tree has the following invariants: All nodes have 0, 1, or 2 children. For all nodes, all keys in the left subtree are smaller; 3 AVL tree invariants review 4 What happens if we insert two elements. What happens? Interlude: Exploring the balance invariant AVL = A delson- V elsky and L andis all keys in the right subtree are larger 6 ◮ What is an invariant ? ◮ What are the AVL tree invariants, exactly? ◮ The “structure” invariant: Question: why abs ( height ( left )) − height ( height ( right )) ≤ 1 ? Why not height ( left ) = height ( right ) ? ◮ The “BST” invariant: ◮ The “balance” invariant: For all nodes, abs ( height ( left )) − height ( height ( right )) ≤ 1 .

  2. AVL tree invariants review Y 4 8 15 Practice: insert 16, and fjx the tree: Practice 10 c Z X 6 a b (Balanced!) Rotate left c Z Y b X 3 10 (Unbalanced!) 3 24 20 16 17 19 22 10 6 4 22 8 15 Step 1: insert 16 Practice 11 24 20 17 19 a Insert “c” Question: ...and what about now? 15 1 Suppose we insert 1, 2, and 3. What happens? A basic example 8 How do we implement an AVL dictionary? Implementing an AVL dictionary 7 11 1 9 7 5 -1 2 6 8 Z 12 2 1 Y b X a (Balanced) Original tree An algorithm for “insert”/“put”, in pictures: AVL rotation 9 3 2 What do we do now? Hint: there’s only one possible solution. Rotate. 3 2 1 ◮ get: Same as BST! ◮ containsKey: Same as BST! ◮ put: ??? ◮ remove: ??? insert(1) insert(2) insert(3)

  3. Practice Handling the “kink” case Step 2: Start from the inserted node and move back up to the 1 3 2 3 1 2 Tree is still unbalanced! 15 The two AVL cases The “line” case The “kink” case 16 Insight: Handling the kink case is hard. Can we somehow convert 1 the kink case into the line case? Solution: Yes, use two rotations! 17 Let’s try again A second attempt... 1 3 2 1 2 3 2 1 3 3 18 24 15 4 10 22 19 8 15 17 16 20 Now, try this. Insert 1, 3, then 2. What’s the issue? 13 Practice Step 3: Rotate left or right to fjx. (Here, we rotate right). 8 6 4 3 6 10 19 17 16 root. Find the fjrst unbalanced subtree. 22 20 24 14 A second case... 3 insert 1 and 3 insert 2 rotate left insert 1, 3, 2 double-rotate: double-rotate: (unbalanced!) convert to line fix tree

  4. The kink case: rotation 1 b b c e a b e a Practice e 21 e b a Initial tree a a a c Practice d rotations to balance tree Implementing AVL operations In summary... In summary... 23 e c a d b c d e a b Practice 22 Try inserting a, b, e, c, d into an AVL tree. b 20 a 19 Z X b d Y c W Fix the inner “b” subtree: After fjxing the “b” subtree Z X d Y c b W a (Unbalanced) The kink case: rotation 2 Z a Z X b d Y W a c Fix the outer “a” subtree: 24 X d W c Y b rotate left on a insert c insert d insert a insert b insert e double rotation on e, double rotation on e, part 1 part 2 ◮ get: Same as BST! ◮ containsKey: Same as BST! ◮ put: Do BST insert, move up tree, perform single or double ◮ remove: Either lazy-delete or use similar method to insert

  5. A note on implementation when the array is full Analyzing ArrayList add Question: what’s the runtime on average ? Core idea: cost of resizing is amortized over the subsequent calls Metaphors: following month We sometimes need to rotate left, rotate right, double-rotate left, amortized and pays itself back over the next several years 28 Analyzing ArrayList’s add c when the array is not full Scenario: when the array is full Let’s suppose the array initially has size k . Let’s also suppose the array initially is at capacity. up to capacity? k 29 Analyzing ArrayList’s add variations Now, what if instead of resizing by doubling, what if we increased the capacity by 100 each time? resize once then fjll back up to capacity? k What is k ? k is the value of n each time we resize. If we plot this, we’ll get a step-wise function that grows linearly! 27 30 25 Analyzing Arraylist add And now, for a completely unrelated topic... when the array is not full 26 Analyzing ArrayList add Exercise: model the worst-case runtime of ArrayList’s add method in terms of n , the number of items inside the list: “bigger” subtree, and the index to the “smaller” subtree) (E.g. we can have “rotate” accept two ints: the index to the so we only have to write two methods: rotate, and double-rotate. of using left or right fjelds. This lets us refer to children by index No: can reduce redundancy by having an array of children instead c Do we need to implement 4 methods? or double-rotate right. public void add(T item) { if (array is full) { resize and copy } this .array[ this .size] = item; this .size += 1; ◮ When you pay rent, that large cost is amortized over the }  ◮ When you buy an expensive machine, that large cost is  Answer: T ( n ) = n + c  So, in the WORST possible case, what’s the runtime? Θ ( n ) .   Our recurrence: T ( n ) = n + c  ◮ Assuming we’re full, how much work do we do in total to 1 · ( k + c ) + 99 · c = k + 100 c ◮ How much work do we need to do to resize once then fjll back ◮ What is the average amount of work done? k + 100 c = 100 + c 1 · ( k + c ) + ( k − 1) · c = k + ck . 100 Note: since array was full, n = k in fjrst resize ◮ What is the average amount of work done? So, add would be in Θ ( n ) . k + ck = 1 + c

  6. Analyzing ArrayList’s add variations Amortized analysis Hooray, physics metaphors? that energy. The data structure has “potential energy”, difgerent operations alter Assign each operation an “amortized cost”, which may difger from Other common techniques (not covered in this class): . n Now, what if instead of resizing by doubling, we triple? This is called amortized analysis . The technique we discussed: 32 31 resize once then fjll back up to capacity? ◮ Aggregate analysis: Show a series of n operations has an upper-bound of T ( n ) . The average cost is then T ( n ) ◮ Assuming we’re full, how much work do we do in total to 1 · ( k + c ) + (2 k − 1) · c = k + 2 kc ◮ The accounting method: ◮ What is the average amount of work done? k + 2 kc = 1 2 + c actual cost. If amortized cost > actual cost, incur credit. Credit is 2 k later used to pay for operations where amortized cost < actual cost. So, add would be in Θ (1) . ◮ The potential method:

Recommend


More recommend