BalancedTree.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
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
00019
00020
00021
00023
00033 template< class Obj >
00034 class BalancedTree
00035 {
00037
00038
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
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
00079
00081 public:
00082
00083 int size( ) const {
00084 if( !theRoot ) return 0;
00085 return theRoot->weight1 + theRoot->weight2 + 1;
00086 }
00087
00089
00090
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
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
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
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 ) {
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 {
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
00197 child->subtree2 = right_left->subtree1;
00198 child->weight2 = right_left->weight1;
00199 child->height2 = right_left->height1;
00200
00201
00202 right->subtree1 = right_left->subtree2;
00203 right->weight1 = right_left->weight2;
00204 right->height1 = right_left->height2;
00205
00206
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 ) {
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
00247 child->subtree1 = left_right->subtree2;
00248 child->weight1 = left_right->weight2;
00249 child->height1 = left_right->height2;
00250
00251
00252 left->subtree2 = left_right->subtree1;
00253 left->weight2 = left_right->weight1;
00254 left->height2 = left_right->height1;
00255
00256
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
00269
00271
00272 private:
00273
00274 BTNode* theRoot;
00275
00276 };
00277
00278
00279 #endif