00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "pana_rbtree.h"
00035
00036 RbTreeNode &RbTreeNode::operator=(RbTreeNode &source)
00037 {
00038 left = source.left;
00039 right = source.right;
00040 parent = source.parent;
00041 color = source.color;
00042 data = source.data;
00043 return (*this);
00044 }
00045
00046 RbTreeNode::RbTreeNode()
00047 {
00048 left = right = this;
00049 parent = (0);
00050 color = RBTREE_CLR_BLACK;
00051 data = (0);
00052 }
00053
00054 void RbTreeTree::RotateLeft(RbTreeNode *x)
00055 {
00056 RbTreeNode *y = x->right;
00057
00058
00059 x->right = y->left;
00060 if (y->left != &nil) {
00061 y->left->parent = x;
00062 }
00063
00064
00065 if (y != &nil) {
00066 y->parent = x->parent;
00067 }
00068 if (x->parent) {
00069 if (x == x->parent->left)
00070 x->parent->left = y;
00071 else
00072 x->parent->right = y;
00073 } else {
00074 root = y;
00075 }
00076
00077
00078 y->left = x;
00079 if (x != &nil) {
00080 x->parent = y;
00081 }
00082 }
00083
00084 void RbTreeTree::RotateRight(RbTreeNode *x)
00085 {
00086 RbTreeNode *y = x->left;
00087
00088
00089 x->left = y->right;
00090 if (y->right != &nil) {
00091 y->right->parent = x;
00092 }
00093
00094
00095 if (y != &nil) {
00096 y->parent = x->parent;
00097 }
00098 if (x->parent) {
00099 if (x == x->parent->right)
00100 x->parent->right = y;
00101 else
00102 x->parent->left = y;
00103 } else {
00104 root = y;
00105 }
00106
00107
00108 y->right = x;
00109 if (x != &nil) {
00110 x->parent = y;
00111 }
00112 }
00113
00114 void RbTreeTree::FixupRemove(RbTreeNode *x)
00115 {
00116 while (x != root && x->color == RBTREE_CLR_BLACK) {
00117 if (x == x->parent->left) {
00118 RbTreeNode *w = x->parent->right;
00119 if (w->color == RBTREE_CLR_RED) {
00120 w->color = RBTREE_CLR_BLACK;
00121 x->parent->color = RBTREE_CLR_RED;
00122 RotateLeft (x->parent);
00123 w = x->parent->right;
00124 }
00125 if (w->left->color == RBTREE_CLR_BLACK && w->right->color == RBTREE_CLR_BLACK) {
00126 w->color = RBTREE_CLR_RED;
00127 x = x->parent;
00128 } else {
00129 if (w->right->color == RBTREE_CLR_BLACK) {
00130 w->left->color = RBTREE_CLR_BLACK;
00131 w->color = RBTREE_CLR_RED;
00132 RotateRight (w);
00133 w = x->parent->right;
00134 }
00135 w->color = x->parent->color;
00136 x->parent->color = RBTREE_CLR_BLACK;
00137 w->right->color = RBTREE_CLR_BLACK;
00138 RotateLeft (x->parent);
00139 x = root;
00140 }
00141 } else {
00142 RbTreeNode *w = x->parent->left;
00143 if (w->color == RBTREE_CLR_RED) {
00144 w->color = RBTREE_CLR_BLACK;
00145 x->parent->color = RBTREE_CLR_RED;
00146 RotateRight (x->parent);
00147 w = x->parent->left;
00148 }
00149 if (w->right->color == RBTREE_CLR_BLACK && w->left->color == RBTREE_CLR_BLACK) {
00150 w->color = RBTREE_CLR_RED;
00151 x = x->parent;
00152 } else {
00153 if (w->left->color == RBTREE_CLR_BLACK) {
00154 w->right->color = RBTREE_CLR_BLACK;
00155 w->color = RBTREE_CLR_RED;
00156 RotateLeft (w);
00157 w = x->parent->left;
00158 }
00159 w->color = x->parent->color;
00160 x->parent->color = RBTREE_CLR_BLACK;
00161 w->left->color = RBTREE_CLR_BLACK;
00162 RotateRight (x->parent);
00163 x = root;
00164 }
00165 }
00166 }
00167 x->color = RBTREE_CLR_BLACK;
00168 }
00169
00170 void RbTreeTree::FixupInsert(RbTreeNode *x)
00171 {
00172
00173 while (x != root && x->parent->color == RBTREE_CLR_RED) {
00174
00175 if (x->parent == x->parent->parent->left) {
00176 RbTreeNode *y = x->parent->parent->right;
00177 if (y->color == RBTREE_CLR_RED) {
00178
00179
00180 x->parent->color = RBTREE_CLR_BLACK;
00181 y->color = RBTREE_CLR_BLACK;
00182 x->parent->parent->color = RBTREE_CLR_RED;
00183 x = x->parent->parent;
00184 } else {
00185
00186
00187 if (x == x->parent->right) {
00188
00189 x = x->parent;
00190 RotateLeft(x);
00191 }
00192
00193
00194 x->parent->color = RBTREE_CLR_BLACK;
00195 x->parent->parent->color = RBTREE_CLR_RED;
00196 RotateRight(x->parent->parent);
00197 }
00198 } else {
00199
00200
00201 RbTreeNode *y = x->parent->parent->left;
00202 if (y->color == RBTREE_CLR_RED) {
00203
00204
00205 x->parent->color = RBTREE_CLR_BLACK;
00206 y->color = RBTREE_CLR_BLACK;
00207 x->parent->parent->color = RBTREE_CLR_RED;
00208 x = x->parent->parent;
00209 } else {
00210
00211
00212 if (x == x->parent->left) {
00213 x = x->parent;
00214 RotateRight(x);
00215 }
00216 x->parent->color = RBTREE_CLR_BLACK;
00217 x->parent->parent->color = RBTREE_CLR_RED;
00218 RotateLeft(x->parent->parent);
00219 }
00220 }
00221 }
00222 root->color = RBTREE_CLR_BLACK;
00223 }
00224
00225 RbTreeData *RbTreeTree::Insert(RbTreeData *data)
00226 {
00227 RbTreeNode *parent = (0), *current = root;
00228
00229 while (current != &nil) {
00230 if (*(current->data) == (*data)) {
00231 return (current->data);
00232 }
00233 parent = current;
00234 current = ((*data) < (*(current->data))) ?
00235 current->left : current->right;
00236 }
00237
00238 current = new RbTreeNode;
00239 if (! current) {
00240 return (0);
00241 }
00242
00243 current->left = current->right = &nil;
00244 current->parent = parent;
00245 current->color = RBTREE_CLR_RED;
00246 current->data = data;
00247
00248 if (parent) {
00249 if ((*data) < (*(parent->data))) {
00250 parent->left = current;
00251 }
00252 else {
00253 parent->right = current;
00254 }
00255 }
00256 else {
00257 root = current;
00258 }
00259
00260 FixupInsert(current);
00261 return (current->data);
00262 }
00263
00264 RbTreeData *RbTreeTree::Find(RbTreeData *data)
00265 {
00266 RbTreeNode *current = root;
00267
00268 while (current != &nil) {
00269 if (*(current->data) == (*data)) {
00270 return (current->data);
00271 }
00272 current = ((*data) < (*(current->data))) ?
00273 current->left : current->right;
00274 }
00275
00276 return (0);
00277 }
00278
00279 RbTreeData *RbTreeTree::Remove(RbTreeData *data)
00280 {
00281 RbTreeData *val;
00282 RbTreeNode *x, *y, *z = root;
00283
00284 while (z != &nil) {
00285 if (*(z->data) == (*data)) {
00286 break;
00287 }
00288 z = ((*data) < (*(z->data))) ? z->left : z->right;
00289 }
00290
00291 if (!z || z == &nil) {
00292 return (0);
00293 }
00294
00295 if (z->left == &nil || z->right == &nil) {
00296
00297 y = z;
00298 } else {
00299
00300 y = z->right;
00301 while (y->left != &nil) {
00302 y = y->left;
00303 }
00304 }
00305
00306
00307 if (y->left != &nil) {
00308 x = y->left;
00309 } else {
00310 x = y->right;
00311 }
00312
00313
00314 x->parent = y->parent;
00315 if (y->parent) {
00316 if (y == y->parent->left) {
00317 y->parent->left = x;
00318 } else {
00319 y->parent->right = x;
00320 }
00321 } else {
00322 root = x;
00323 }
00324
00325 if (y != z) {
00326 val = z->data;
00327 z->data = y->data;
00328 }
00329 else {
00330 val = y->data;
00331 }
00332
00333 if (y->color == RBTREE_CLR_BLACK) {
00334 FixupRemove(x);
00335 }
00336
00337 delete y;
00338 return (val);
00339 }
00340
00341 void RbTreeTree::Clear(void *userData)
00342 {
00343 RbTreeData *val;
00344 while (root != &nil) {
00345 val = RbTreeTree::Remove(root->data);
00346 val->clear(userData);
00347 delete val;
00348 }
00349 }
00350
00351 void RbTreeTree::Dump(RbTreeNode *x, void *userData)
00352 {
00353 if (x == 0) {
00354 x = root;
00355 }
00356 if (x == &nil) {
00357 return;
00358 }
00359 if (x->left != &nil) {
00360 Dump(x->left, userData);
00361 }
00362 if (x->data) {
00363 x->data->Dump(userData);
00364 } else {
00365 }
00366 if (x->right != &nil) {
00367 Dump(x->right, userData);
00368 }
00369 }