370 likes | 469 Vues
Week 8 - Friday. CS221. Last time. What did we talk about last time? BST deletion AVL trees. Questions?. Project 3. Assignment 4. Balancing a Tree by Construction. How to make a balanced tree. What if we knew ahead of time which numbers we were going to put into a tree?
E N D
Week 8 - Friday CS221
Last time • What did we talk about last time? • BST deletion • AVL trees
How to make a balanced tree • What if we knew ahead of time which numbers we were going to put into a tree? • How could we make sure the tree is balanced? • Answer: • Sort the numbers • Recursively add the numbers such that the tree stays balanced
Balanced insertion • Write a recursive method that adds a sorted array of data such that the tree stays balanced • Assume that an add(int key)method exists • Use the usual convention that start is the beginning of a range and end is the location after the last legal element in the range public void balance(int[] data, int start, int end )
DSW algorithm • Takes a potentially unbalanced tree and turns it into a balanced tree • Step 1 • Turn the tree into a degenerate tree (backbone or vine) by right rotating any nodes with left children • Step 2 • Turn the degenerate tree into a balanced tree by doing sequences of left rotations starting at the root • The analysis is not obvious, but it takes O(n) total rotations
Which method is best? • How much time does it take to insert n items with: • AVL tree • Balanced insertion method • Unbalanced insertion + DSW rebalance • How much space does it take to insert n items with: • AVL tree • Balanced insertion method • Unbalanced insertion + DSW rebalance
Self-Adjusting Trees • Balanced binary trees ensure that accessing any element takes O(log n) time • But, maybe only a few elements are accessed repeatedly • In this case, it may make more sense to restructure the tree so that these elements are closer to the root
Restructuring strategies • Single rotation • Rotate a child about its parent if an element in a child is accessed, unless it's the root • Moving to the root • Repeat the child-parent rotation until the element being accessed is the root
Splaying • A concept called splaying takes the rotate to the root idea further, doing special rotations depending on the relationship of the child R with its parent Q and grandparent P • Cases: • Node R's parent is the root • Do a single rotation to make R the root • Node R is the left child of Q and Q is the left child of P (respectively right and right) • Rotate Q around P • Rotate R around Q • Node R is the left child of Q and Q is the right child of P (respectively right and left) • Rotate R around Q • Rotate R around P
Danger, Will Robinson! • We are not going deeply into self-organizing trees • It's an interesting concept, and rigorous mathematical analysis shows that splay trees should perform well, in terms of Big O bounds • In practice, however, they usually do not • An AVL tree or a red-black tree is generally the better choice • If you come upon some special problem where you repeatedly access a particular element most of the time, only then should you consider splay trees
Heaps • A maximum heap is a complete binary tree where • The left and right children of the root have key values less than the root • The left and right subtrees are also maximum heaps • We can define minimum heaps similarly
Heap example 10 9 3 0 1
How do you know where to add? • Easy! • We look at the location of the new node in binary • Ignore the first 1, then each 0 is for going left, each 1 is for going right
New node 10 • Location: 6 • In binary: 110 • Right then left 9 3 0 1
Add 15 10 • Oh no! 9 3 0 1 15
After an add, bubble up 10 15 10 9 9 9 15 3 10 0 0 0 1 1 1 15 3 3
Only the root can be deleted 10 9 3 0 1
Replace it with the “last” node 1 9 9 3 3 0 0 1
Then, bubble down 1 9 9 1 3 3 0 0
Operations • Heaps only have: • Add • Remove Largest • Get Largest • Which cost: • Add: O(log n) • Remove Largest: O(log n) • Get Largest: O(1) • Heaps are a perfect data structure for a priority queue
Tree implementation of heap public class Heap { private static class Node { public int key; public Node left; public Node right; } private Node root = null; private intsize = 0; … }
Add private Node add(Node tree, int key, int power) Proxy: public voidadd(int key) { intpower = powerOf(size + 1) / 2; root = add( root, key, power ); size++; } Find where the node should be using the binary representation. Put a node there. We need a helper method that gives us the value of the highest power of 2 (the value itself, not the exponent) that is less than or equal to a number: private static intpowerOf(int value)
Get Largest public intgetLargest()
Remove Largest private intremove(Node tree, power) Proxy: public voidremove() { if( size > 1 ) { power = powerOf(size) / 2; root.key = remove( root, power ); bubbleDown( root ); } else root = null; size--; } Find the last value in the heap and remove it, returning the value. Put the value in the root node and bubble it down. We need a helper method to bubble down the value: private static intbubbleDown(Node root)
Array view 10 • We can implement a heap with a (dynamic) array • The left child of element i is at 2i + 1 • The right child of element i is at 2i + 2 9 3 0 10 9 1 3 2 0 3 1 4 0 1
Array implementation of heap public class Heap { private int[] values = new int[10]; private intsize = 0; … }
Next time… • Finish heaps • B-trees
Reminders • Keep working on Project 3 • Finish Assignment 4 • Due tonight by midnight