home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ledar34.zip / leda-r-3_4_tar / LEDA-3.4 / src / dict / _avl_tree.c < prev    next >
C/C++ Source or Header  |  1996-09-03  |  4KB  |  171 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA 3.4
  4. +
  5. +  _avl_tree.c
  6. +
  7. +  This file is part of the LEDA research version (LEDA-R) that can be 
  8. +  used free of charge in academic research and teaching. Any commercial
  9. +  use of this software requires a license which is distributed by the
  10. +  LEDA Software GmbH, Postfach 151101, 66041 Saarbruecken, FRG
  11. +  (fax +49 681 31104).
  12. +
  13. +  Copyright (c) 1991-1996  by  Max-Planck-Institut fuer Informatik
  14. +  Im Stadtwald, 66123 Saarbruecken, Germany     
  15. +  All rights reserved.
  16. *******************************************************************************/
  17. #include <LEDA/impl/avl_tree.h>
  18.  
  19.  
  20. //----------------------------------------------------------------------------
  21. //  avl_tree:
  22. //
  23. //  rebalancing routines for AVL trees
  24. //
  25. //  S. N"aher (1993)
  26. //----------------------------------------------------------------------------
  27.  
  28.  
  29. void avl_tree::insert_rebal(avl_tree_item v)
  30. {
  31.   // preconditions:  v is new node created by insertion
  32.   //                 v != root
  33.   //                 height(v) == 1, bal(v) == 0;
  34.  
  35.   // bal(v) == height(R) - height(L)           
  36.  
  37.   //                    u
  38.   //                    |
  39.   //                    v
  40.   //                   / \ 
  41.   //                  L   R
  42.   //
  43.  
  44.   
  45.   while ( v != root() )
  46.   {
  47.     avl_tree_item u = v->parent;
  48.  
  49.     int dir = (v == u->child[left]) ? left : right;
  50.  
  51.     int b = u->get_bal();
  52.  
  53.     if (dir==left)   // insertion in left subtree of u 
  54.        b--;
  55.     else             // insertion in right subtree of u
  56.        b++; 
  57.  
  58.     u->set_bal(b);
  59.  
  60.     if (b==0)  break;   // height of u has not changed 
  61.  
  62.     if (b != 1 && b != -1)
  63.     { 
  64.       // u is out of balance (-2 or + 2)
  65.  
  66.       int d = (b < 0) ? -1 : +1;
  67.   
  68.       avl_tree_item w = u->child[dir];
  69.   
  70.       if (w->get_bal() == d)
  71.       { rotation(u,w,dir);
  72.         u->set_bal(0);
  73.         w->set_bal(0);
  74.        }
  75.       else
  76.       { avl_tree_item x = w->child[1-dir];
  77.         double_rotation(u,w,x,dir);
  78.  
  79.         if (x->get_bal() == d)
  80.            u->set_bal(-d);
  81.         else
  82.            u->set_bal(0);
  83.   
  84.         if (x->get_bal() == -d)
  85.            w->set_bal(d);
  86.         else
  87.            w->set_bal(0);
  88.   
  89.         x->set_bal(0);
  90.        }
  91.   
  92.       break;
  93.     }
  94.  
  95.     v = u;
  96.  
  97.   }
  98.  
  99. }
  100.  
  101.  
  102. void avl_tree::del_rebal(avl_tree_item v, avl_tree_item)
  103. {
  104.   // precondition:    p is removed inner node
  105.   //                  v is remaining child of p (already linked to parent u)
  106.   //                  v != root
  107.  
  108.   
  109.   while ( v != root() )
  110.   {
  111.     avl_tree_item u = v->parent;
  112.  
  113.     int dir = (v == u->child[left]) ? left : right;
  114.  
  115.     int b = u->get_bal();
  116.  
  117.     if (dir==left)  // deletion in left  subtree of u
  118.        b++;
  119.     else            // deletion in right subtree of u
  120.        b--;
  121.  
  122.     u->set_bal(b);
  123.  
  124.     if (b == 1 || b == -1) break;   // height of u has not changed
  125.  
  126.     if (b != 0)
  127.     { 
  128.       // u is out of balance (-2 or + 2)
  129.  
  130.       int d = (b < 0) ? -1 : +1;
  131.   
  132.       avl_tree_item w = u->child[1-dir];
  133.   
  134.       if (d * w->get_bal() >= 0)
  135.       { rotation(u,w,1-dir);
  136.         if (w->get_bal() == 0)
  137.           { u->set_bal(d);
  138.             w->set_bal(-d);
  139.             break;
  140.            }
  141.         else
  142.           { u->set_bal(0);
  143.             w->set_bal(0);
  144.            }
  145.         v = w;
  146.        }
  147.       else
  148.       { avl_tree_item x = w->child[dir];
  149.         double_rotation(u,w,x,1-dir);
  150.  
  151.         if (x->get_bal() == d)
  152.            u->set_bal(-d);
  153.         else
  154.            u->set_bal(0);
  155.   
  156.         if (x->get_bal() == -d)
  157.            w->set_bal(d);
  158.         else
  159.            w->set_bal(0);
  160.   
  161.         x->set_bal(0);
  162.         v = x;
  163.        }
  164.     }
  165.  
  166.     else v = u;
  167.  
  168.   }
  169. }
  170.