BalancedTree.h

Go to the documentation of this file.
00001 // Copyright (C) 2005 Alexander Ushakov
00002 // Contents: Definition of class BalancedTree
00003 //
00004 // Principal Authors: Alexander Ushakov
00005 //
00006 // Revision History:
00007 //
00008 
00009 
00010 #ifndef _BalancedTree_H_
00011 #define _BalancedTree_H_
00012 
00013 #include "list"
00014 #include "iostream"
00015 using namespace std;
00016 
00017 //---------------------------------------------------------------------------//
00018 //------------------------------ BalancedTree -------------------------------//
00019 //---------------------------------------------------------------------------//
00020 
00021 
00023 
00033 template< class Obj >
00034 class BalancedTree
00035 {
00037   //                                                     //
00038   //  Internal structures:                               //
00039   //                                                     //
00041 
00042  private:
00043   
00044   struct BTNode {
00045     BTNode(         ) : subtree1(0), subtree2(0), height1(0), height2(0), weight1(0), weight2(0) { }
00046     BTNode( Obj obj ) : subtree1(0), subtree2(0), height1(0), height2(0), weight1(0), weight2(0), theObject(obj) { }
00047     ~BTNode( ) {
00048       if( subtree1 ) delete subtree1;
00049       if( subtree2 ) delete subtree2;
00050     }
00051 
00052     Obj     theObject;
00053     BTNode* subtree1;   int height1;  int weight1;
00054     BTNode* subtree2;   int height2;  int weight2;
00055   };
00056 
00058   //                                                     //
00059   //  Constructors                                       //
00060   //                                                     //
00062 
00063  public:
00064 
00066   BalancedTree( ) : theRoot(0) { }
00068   template< class ConstObjIter > BalancedTree( const ConstObjIter& B , const ConstObjIter& E ) : theRoot(0) {
00069     insert( 0 , B , E );
00070   }
00072   ~BalancedTree( ) {
00073     if( theRoot ) delete theRoot;
00074   }
00075   
00077   //                                                     //
00078   //  Operators                                          //
00079   //                                                     //
00081  public:
00082 
00083   int size( ) const {
00084     if( !theRoot ) return 0;
00085     return theRoot->weight1 + theRoot->weight2 + 1;
00086   }
00087 
00089   //                                                     //
00090   //  Accessors                                          //
00091   //                                                     //
00093         
00094 public:
00095 
00097   template< class ConstObjIter > 
00098   void insert( int pos , const ConstObjIter& B , const ConstObjIter& E ) {
00099     int i=pos;
00100     for( ConstObjIter it=B ; it!=E ; ++it, ++i )
00101       insert( i , *it );
00102   }
00103   
00105   void insert( int pos , const Obj& obj ) {
00106     if( theRoot==0 )
00107       theRoot = new BTNode( obj );
00108     else
00109       insert( NULL , theRoot, pos, obj );
00110   }
00111 
00113   list< Obj > getList( ) const {
00114     list< Obj > result;
00115     getList( theRoot , result );
00116     return result;
00117   }
00118 
00120   //                                                     //
00121   //  Internal functions                                 //
00122   //                                                     //
00124 
00125  private:
00126 
00128   void getList( BTNode* node , list< Obj >& result ) const {
00129     if( !node ) return;
00130     getList( node->subtree1 , result );
00131     result.push_back( node->theObject );
00132     getList( node->subtree2 , result );
00133   }
00134 
00136   void insert( BTNode* parent , BTNode* node , int offset , const Obj& obj ) {
00137 
00138     // going down to insert a new element
00139     if( offset<=node->weight1 ) {
00140       if( node->weight1==0 )
00141         node->subtree1 = new BTNode( obj );
00142       else
00143         insert( node , node->subtree1 , offset , obj );
00144       node->weight1++;
00145       node->height1 = 1 +
00146         ( node->subtree1->height1 > node->subtree1->height2 ? 
00147           node->subtree1->height1 : node->subtree1->height2 ); 
00148     } else {
00149       if( !node->subtree2 )
00150         node->subtree2 = new BTNode( obj );
00151       else
00152         insert( node , node->subtree2 , offset-node->weight1-1 , obj );
00153       node->weight2++;
00154       node->height2 = 1 +
00155         ( node->subtree2->height1 > node->subtree2->height2 ? 
00156           node->subtree2->height1 : node->subtree2->height2 ); 
00157     }
00158 
00159     // going up and balance the branches if required
00160     if( node->height1<=node->height2-2 ) {
00161       rotateLeft( parent , node );
00162     } else if( node->height1-2>=node->height2 ) {
00163       rotateRight( parent , node );
00164     }
00165   }
00166 
00168   void rotateLeft( BTNode* parent , BTNode* child ) {
00169     BTNode* right = child->subtree2;
00170     if( right->height1<=right->height2 ) { // 1st type of rotation
00171       if( parent ) {
00172         if( child==parent->subtree1 )
00173           parent->subtree1 = right;
00174         else
00175           parent->subtree2 = right;
00176       } else
00177         theRoot = right;
00178       child->subtree2 = right->subtree1;
00179       right->subtree1 = child;
00180 
00181       child->height2 = right->height1;
00182       child->weight2 = right->weight1;
00183       right->height1 = ( child->height1 > child->height2 ? child->height1 : child->height2 ) + 1;
00184       right->weight1 = child->weight1 + child->weight2 + 1;
00185     } else { // 2nd type of rotation
00186       BTNode* right_left = right->subtree1;
00187 
00188       if( parent ) {
00189         if( child==parent->subtree1 )
00190           parent->subtree1 = right_left;
00191         else
00192           parent->subtree2 = right_left;
00193       } else
00194         theRoot = right_left;
00195       
00196       // child
00197       child->subtree2 = right_left->subtree1;
00198       child->weight2 = right_left->weight1;
00199       child->height2 = right_left->height1;
00200       
00201       // right
00202       right->subtree1 = right_left->subtree2;
00203       right->weight1 = right_left->weight2;
00204       right->height1 = right_left->height2;
00205       
00206       // right_left
00207       right_left->subtree1 = child;
00208       right_left->height1 = ( child->height1 > child->height2 ? child->height1 : child->height2 ) + 1;
00209       right_left->weight1 = child->weight1 + child->weight2 + 1;
00210       right_left->subtree2 = right;
00211       right_left->height2 = ( right->height1 > right->height2 ? right->height1 : right->height2 ) + 1;
00212       right_left->weight2 = right->weight1 + right->weight2 + 1;
00213     }
00214   }
00215 
00217   void rotateRight( BTNode* parent , BTNode* child ) {
00218     BTNode* left = child->subtree1;
00219     if( left->height2<=left->height1 ) { // 1st type of rotation
00220       
00221       if( parent ) {
00222         if( child==parent->subtree1 )
00223           parent->subtree1 = left;
00224         else
00225           parent->subtree2 = left;
00226       } else
00227       theRoot = left;
00228       child->subtree1 = left->subtree2;
00229       left->subtree2 = child;
00230       
00231       child->height1 = left->height2;
00232       child->weight1 = left->weight2;
00233       left->height2 = ( child->height1 > child->height2 ? child->height1 : child->height2 ) + 1;
00234       left->weight2 = child->weight1 + child->weight2 + 1;
00235 
00236     } else {
00237       BTNode* left_right = left->subtree2;
00238       if( parent ) {
00239         if( child==parent->subtree1 )
00240           parent->subtree1 = left_right;
00241         else
00242           parent->subtree2 = left_right;
00243       } else
00244         theRoot = left_right;
00245       
00246       // child
00247       child->subtree1 = left_right->subtree2;
00248       child->weight1  = left_right->weight2;
00249       child->height1  = left_right->height2;
00250       
00251       // left
00252       left->subtree2 = left_right->subtree1;
00253       left->weight2  = left_right->weight1;
00254       left->height2  = left_right->height1;
00255       
00256       // right_left
00257       left_right->subtree1 = left;
00258       left_right->height1 = ( left->height1 > left->height2 ? left->height1 : left->height2 ) + 1;
00259       left_right->weight1 = left->weight1 + left->weight2 + 1;
00260       left_right->subtree2 = child;
00261       left_right->height2 = ( child->height1 > child->height2 ? child->height1 : child->height2 ) + 1;
00262       left_right->weight2 = child->weight1 + child->weight2 + 1;
00263     }
00264   }
00265 
00267   //                                                     //
00268   //  Data members                                       //
00269   //                                                     //
00271 
00272 private:
00273   
00274   BTNode* theRoot;
00275 
00276 };
00277 
00278 
00279 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Mon Sep 26 18:43:45 2011 for CRyptography And Groups (CRAG) by  doxygen 1.6.1