1 / 39

AVL Tree

AVL Tree. is a binary search tree that. For each node: The height of its left and right subtree can only differ at most 1. If a tree is an empty tree , we let its height == -1 . The height of an AVL tree is log N The exact figure is 1.44log(N+2)-.328

mchristy
Télécharger la présentation

AVL Tree

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. AVL Tree

  2. isa binary search tree that • For each node: • The height of its left and right subtree can only differ at most 1. • If a tree is an empty tree, we let its height == -1. • The height of anAVL tree is log N • The exact figure is1.44log(N+2)-.328 • The height difference constraint leads to: • The minimal number of nodes for a tree of height h, s(h) = s(h-1)+s(h-2)+1 • When h=0, s(h) =1 • When h=1, s(h) =2 • This is similar to fibonacci.

  3. 1 1 1 1 AVL Non-AVL

  4. 0 1 1 Inserting a new node here destroys AVL. Various functions • All functions are O(log(N)), except insert and remove -> these may destroy the properties of AVL.

  5. Fix insert+ remove with rotation insert • Only nodes on the path from the insertion point to the root have a chance of height change. • If we follow up from the inserted node, we will eventually find the deepest node that loses its AVL property. We will fix such node. There can only be 4 types of such node.

  6. Solve by single rotation Solve by double rotation • The 4 types:

  7. Pull up a b Move the attachment place to the problem node. a b Z X X Y Y Z If it is fixed now, no further rotation is needed. Single rotation afterinsert

  8. 5 This node loses AVL property. 5 2 8 2 7 0 1 1 4 7 1 4 6 8 1 3 6 3 example1

  9. 3 3 3 rotate 2 2 2 1 1 3 Example 2 • Starting from nothing, weinsert 3,2,1 losesAVL To be continued

  10. 2 losesAVL 2 1 3 1 3 4 2 4 5 1 4 3 5 To be continued Then weinsert 4,5

  11. losesAVL rotate 4 2 5 2 1 3 1 6 4 6 3 5 • Then weinsert 6 To be continued

  12. losesAVL 4 4 2 rotate 5 2 6 1 3 1 3 6 5 7 7 Then weinsert 7

  13. a b b a Z X Y X Y Z Double rotation • When Single rotation is useless Y does not change level

  14. Loses AVL a a b b Z Z X Y c X Insertion takes place. There must be something in. Y1 Y2

  15. a a c b Z Z c b X Y2 X Y1 Y2 Y1 The first rotation

  16. a c c b a Z b X Y2 Y1 Y2 Z X Y1 the second rotation

  17. It is like lettingc releaseY1,Y2 and carry a and b instead. c a a b b Z c X X Z Y1 Y2 Y1 Y2 Y1, Y2find places to attach • We do not know whether Y1 or Y2 is the cause. But it does not matter because in the end both of them reduce in level.

  18. 4 4 2 6 2 Loses AVL 6 rotate 1 3 5 7 1 3 5 15 16 7 16 15 example • Insert 16,15: losesAVL when inserting 15

  19. Loses AVL 4 4 2 rotate 6 2 7 1 3 5 1 15 3 6 15 7 16 5 14 16 Must jump 14 • Insert 14

  20. Two right moves:single rotation 4 7 2 7 4 15 1 3 rotate 6 15 2 6 14 16 5 14 16 1 3 5 13 13 Loses AVL • Insert 13

  21. 7 4 15 2 6 14 16 1 3 5 13 7 4 • Insert 12: this is an obvious single rotation Loses AVL 15 rotate 2 6 13 16 1 3 5 12 14 12

  22. 7 Loses AVL 7 4 4 • Insert 11: another single rotation 13 15 rotate 15 12 2 6 6 13 2 16 1 3 1 14 16 5 3 5 12 14 11 11

  23. 7 4 13 Loses AVL rotate 15 12 6 2 1 14 16 5 3 11 10 7 4 • Insert 10: another single rotation 13 15 6 11 2 14 16 5 3 1 10 12

  24. 7 4 13 • Insert 8 • Insert 9: simple double rotation 6 Loses AVL 15 2 11 5 3 1 10 12 14 16 8 9 10 8 9

  25. class AvlNode • { • // Constructors • AvlNode( Comparable theElement ) • { • this( theElement, null, null ); • } • AvlNode( Comparable theElement, AvlNode lt, AvlNode rt ) • { • element = theElement; • left = lt; • right = rt; • height = 0; • } • // Friendly data; accessible by other package routines • Comparable element; // The data in the node • AvlNode left; // Left child • AvlNode right; // Right child • int height; // Height • } There will be a method that returnsheight. So we do not have to worry if the node we are looking at is null.

  26. public class AvlTree • { private AvlNode root; • /** • * Construct the tree. • */ • public AvlTree( ) • { • root = null; • } • /** • * Insert into the tree; duplicates are ignored. • * @param x the item to insert. • */ • public void insert( Comparable x ) • { • root = insert( x, root ); • }

  27. Same as binary search Tree • /** • * Find the smallest item in the tree. • * @return smallest item or null if empty. • */ • public Comparable findMin( ) • { • return elementAt( findMin( root ) ); • } • /** • * Find the largest item in the tree. • * @return the largest item of null if empty. • */ • public Comparable findMax( ) • { • return elementAt( findMax( root ) ); • }

  28. /** • * Return the height of node t, or -1, if null. • */ • private static int height( AvlNode t ) • { • return t == null ? -1 : t.height; • } • /** • * Return maximum of lhs and rhs. • */ • private static int max( int lhs, int rhs ) • { • return lhs > rhs ? lhs : rhs; • } Helper functions

  29. t Insert • /** • * Internal method to insert into a subtree. • * @param x the item to insert. • * @param t the node that roots the tree. • * @return the new root. • */ • private AvlNode insert( Comparable x, AvlNode t ) • { • if( t == null ) • t = new AvlNode( x, null, null ); • else if( x.compareTo( t.element ) < 0 ) • { • t.left = insert( x, t.left ); • if( height( t.left ) - height( t.right ) == 2 ) • if( x.compareTo( t.left.element ) < 0 ) • t = rotateWithLeftChild( t ); • else • t = doubleWithLeftChild( t ); • } If = =2 is true, x is below.

  30. t • else if( x.compareTo( t.element ) > 0 ) • { • t.right = insert( x, t.right ); • if( height( t.right ) - height( t.left ) == 2 ) • if( x.compareTo( t.right.element ) > 0 ) • t = rotateWithRightChild( t ); • else • t = doubleWithRightChild( t ); • } • else • ; // Duplicate; do nothing • t.height = max( height( t.left ), height( t.right ) ) + 1; • return t; • }

  31. k2 k1 k1 k2 • /** • * Rotate binary tree node with left child. • * For AVL trees, this is a single rotation for case 1. • * Update heights, then return new root. • */ • private static AvlNode rotateWithLeftChild( AvlNode k2 ) • { • AvlNode k1 = k2.left; • k2.left = k1.right; • k1.right = k2; • k2.height = max( height( k2.left ), height( k2.right ) ) + 1; • k1.height = max( height( k1.left ), k2.height ) + 1; • return k1; • }

  32. k1 k2 k2 k1 • /** • * Rotate binary tree node with right child. • * For AVL trees, this is a single rotation for case 4. • * Update heights, then return new root. • */ • private static AvlNode rotateWithRightChild( AvlNode k1 ) • { • AvlNode k2 = k1.right; • k1.right = k2.left; • k2.left = k1; • k1.height = max( height( k1.left ), height( k1.right ) ) + 1; • k2.height = max( height( k2.right ), k1.height ) + 1; • return k2; • }

  33. k3 k3 k1 k2 Z k2 Z k2 k1 k3 X k1 Y2 X Z Y1 Y2 X Y1 Y2 Y1 • /** • * Double rotate binary tree node: first left child • * with its right child; then node k3 with new left child. • * For AVL trees, this is a double rotation for case 2. • * Update heights, then return new root. • */ • private static AvlNode doubleWithLeftChild( AvlNode k3 ) • { • k3.left = rotateWithRightChild( k3.left ); • return rotateWithLeftChild( k3 ); • }

  34. k1 k1 k2 k3 Z k2 Z k1 k3 k2 X k3 Y2 X Y1 Z Y2 Y2 Y1 X Y1 • /** • * Double rotate binary tree node: first right child • * with its left child; then node k1 with new right child. • * For AVL trees, this is a double rotation for case 3. • * Update heights, then return new root. • */ • private static AvlNode doubleWithRightChild( AvlNode k1 ) • { • k1.right = rotateWithLeftChild( k1.right ); • return rotateWithRightChild( k1 ); • }

  35. Remove a node from AVL • First, do a normal remove • Then rebalance, starting from the node just above the removed node up to the root. • We need to rebalance every node because balancing a child can make its parent loses AVL.

  36. Loses AVL Loses AVL

  37. private AVLNode basicRemove( Comparable x, AVLNode t ) { if( t == null ) return t; // Item not found; do nothing if( x.compareTo( t.element ) < 0 ) t.left = basicRemove( x, t.left ); else if( x.compareTo( t.element ) > 0 ) t.right = basicRemove( x, t.right ); else if( t.left != null && t.right != null ) // Two children { t.element = findMin( t.right ).element; t.right = basicRemove( t.element, t.right ); } else t = ( t.left != null ) ? t.left : t.right; t.setHeight(); return t; } This is the same as BinaryNode’s remove()

  38. private AVLNode remove(Comparable x, AVLNode r){ r = basicRemove(x,r); r = rebalance(r); return r; } public void remove(Comparable x){ root = remove(x, root); } private void setHeight(){// this is in AVLNode height = 1 + Math.max(height(left), height(right)); } private static int height(AVLNode n){ // this is in AVLNode return (n == null ? -1 : n.height); }

  39. private AVLNode rebalance(AVLNode r){ if (r == null) return r; int balance = balanceValue(r); if (balance == 2){//left hand side has more nodes than it should have if (balanceValue(r.left) ==-1) r.left = rotateWithRightChild(r.left); r = rotateWithLeftChild(r); } else if (balance == -2){//right hand side has more nodes than it should have if (balanceValue(r.right) ==1) r.right = rotateWithLeftChild(r.right); r = rotateWithRightChild(r); } r.setHeight(); return r; } public int balanceValue(AvlNode t){ return height(t.left) – height(t.right); }

More Related