1 // RB tree utilities implementation -*- C++ -*- 2 3 // Copyright (C) 2003, 2005 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 2, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // You should have received a copy of the GNU General Public License along 17 // with this library; see the file COPYING. If not, write to the Free 18 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19 // USA. 20 21 // As a special exception, you may use this file as part of a free software 22 // library without restriction. Specifically, if other files instantiate 23 // templates or use macros or inline functions from this file, or you compile 24 // this file and link it with other files to produce an executable, this 25 // file does not by itself cause the resulting executable to be covered by 26 // the GNU General Public License. This exception does not however 27 // invalidate any other reasons why the executable file might be covered by 28 // the GNU General Public License. 29 30 /* 31 * 32 * Copyright (c) 1996,1997 33 * Silicon Graphics Computer Systems, Inc. 34 * 35 * Permission to use, copy, modify, distribute and sell this software 36 * and its documentation for any purpose is hereby granted without fee, 37 * provided that the above copyright notice appear in all copies and 38 * that both that copyright notice and this permission notice appear 39 * in supporting documentation. Silicon Graphics makes no 40 * representations about the suitability of this software for any 41 * purpose. It is provided "as is" without express or implied warranty. 42 * 43 * 44 * Copyright (c) 1994 45 * Hewlett-Packard Company 46 * 47 * Permission to use, copy, modify, distribute and sell this software 48 * and its documentation for any purpose is hereby granted without fee, 49 * provided that the above copyright notice appear in all copies and 50 * that both that copyright notice and this permission notice appear 51 * in supporting documentation. Hewlett-Packard Company makes no 52 * representations about the suitability of this software for any 53 * purpose. It is provided "as is" without express or implied warranty. 54 * 55 * 56 */ 57 58 #include <bits/stl_tree.h> 59 60 _GLIBCXX_BEGIN_NAMESPACE(std) 61 62 _Rb_tree_node_base* 63 _Rb_tree_increment(_Rb_tree_node_base* __x) 64 { 65 if (__x->_M_right != 0) 66 { 67 __x = __x->_M_right; 68 while (__x->_M_left != 0) 69 __x = __x->_M_left; 70 } 71 else 72 { 73 _Rb_tree_node_base* __y = __x->_M_parent; 74 while (__x == __y->_M_right) 75 { 76 __x = __y; 77 __y = __y->_M_parent; 78 } 79 if (__x->_M_right != __y) 80 __x = __y; 81 } 82 return __x; 83 } 84 85 const _Rb_tree_node_base* 86 _Rb_tree_increment(const _Rb_tree_node_base* __x) 87 { 88 return _Rb_tree_increment(const_cast<_Rb_tree_node_base*>(__x)); 89 } 90 91 _Rb_tree_node_base* 92 _Rb_tree_decrement(_Rb_tree_node_base* __x) 93 { 94 if (__x->_M_color == _S_red 95 && __x->_M_parent->_M_parent == __x) 96 __x = __x->_M_right; 97 else if (__x->_M_left != 0) 98 { 99 _Rb_tree_node_base* __y = __x->_M_left; 100 while (__y->_M_right != 0) 101 __y = __y->_M_right; 102 __x = __y; 103 } 104 else 105 { 106 _Rb_tree_node_base* __y = __x->_M_parent; 107 while (__x == __y->_M_left) 108 { 109 __x = __y; 110 __y = __y->_M_parent; 111 } 112 __x = __y; 113 } 114 return __x; 115 } 116 117 const _Rb_tree_node_base* 118 _Rb_tree_decrement(const _Rb_tree_node_base* __x) 119 { 120 return _Rb_tree_decrement(const_cast<_Rb_tree_node_base*>(__x)); 121 } 122 123 void 124 _Rb_tree_rotate_left(_Rb_tree_node_base* const __x, 125 _Rb_tree_node_base*& __root) 126 { 127 _Rb_tree_node_base* const __y = __x->_M_right; 128 129 __x->_M_right = __y->_M_left; 130 if (__y->_M_left !=0) 131 __y->_M_left->_M_parent = __x; 132 __y->_M_parent = __x->_M_parent; 133 134 if (__x == __root) 135 __root = __y; 136 else if (__x == __x->_M_parent->_M_left) 137 __x->_M_parent->_M_left = __y; 138 else 139 __x->_M_parent->_M_right = __y; 140 __y->_M_left = __x; 141 __x->_M_parent = __y; 142 } 143 144 void 145 _Rb_tree_rotate_right(_Rb_tree_node_base* const __x, 146 _Rb_tree_node_base*& __root) 147 { 148 _Rb_tree_node_base* const __y = __x->_M_left; 149 150 __x->_M_left = __y->_M_right; 151 if (__y->_M_right != 0) 152 __y->_M_right->_M_parent = __x; 153 __y->_M_parent = __x->_M_parent; 154 155 if (__x == __root) 156 __root = __y; 157 else if (__x == __x->_M_parent->_M_right) 158 __x->_M_parent->_M_right = __y; 159 else 160 __x->_M_parent->_M_left = __y; 161 __y->_M_right = __x; 162 __x->_M_parent = __y; 163 } 164 165 void 166 _Rb_tree_insert_and_rebalance(const bool __insert_left, 167 _Rb_tree_node_base* __x, 168 _Rb_tree_node_base* __p, 169 _Rb_tree_node_base& __header) 170 { 171 _Rb_tree_node_base *& __root = __header._M_parent; 172 173 // Initialize fields in new node to insert. 174 __x->_M_parent = __p; 175 __x->_M_left = 0; 176 __x->_M_right = 0; 177 __x->_M_color = _S_red; 178 179 // Insert. 180 // Make new node child of parent and maintain root, leftmost and 181 // rightmost nodes. 182 // N.B. First node is always inserted left. 183 if (__insert_left) 184 { 185 __p->_M_left = __x; // also makes leftmost = __x when __p == &__header 186 187 if (__p == &__header) 188 { 189 __header._M_parent = __x; 190 __header._M_right = __x; 191 } 192 else if (__p == __header._M_left) 193 __header._M_left = __x; // maintain leftmost pointing to min node 194 } 195 else 196 { 197 __p->_M_right = __x; 198 199 if (__p == __header._M_right) 200 __header._M_right = __x; // maintain rightmost pointing to max node 201 } 202 // Rebalance. 203 while (__x != __root 204 && __x->_M_parent->_M_color == _S_red) 205 { 206 _Rb_tree_node_base* const __xpp = __x->_M_parent->_M_parent; 207 208 if (__x->_M_parent == __xpp->_M_left) 209 { 210 _Rb_tree_node_base* const __y = __xpp->_M_right; 211 if (__y && __y->_M_color == _S_red) 212 { 213 __x->_M_parent->_M_color = _S_black; 214 __y->_M_color = _S_black; 215 __xpp->_M_color = _S_red; 216 __x = __xpp; 217 } 218 else 219 { 220 if (__x == __x->_M_parent->_M_right) 221 { 222 __x = __x->_M_parent; 223 _Rb_tree_rotate_left(__x, __root); 224 } 225 __x->_M_parent->_M_color = _S_black; 226 __xpp->_M_color = _S_red; 227 _Rb_tree_rotate_right(__xpp, __root); 228 } 229 } 230 else 231 { 232 _Rb_tree_node_base* const __y = __xpp->_M_left; 233 if (__y && __y->_M_color == _S_red) 234 { 235 __x->_M_parent->_M_color = _S_black; 236 __y->_M_color = _S_black; 237 __xpp->_M_color = _S_red; 238 __x = __xpp; 239 } 240 else 241 { 242 if (__x == __x->_M_parent->_M_left) 243 { 244 __x = __x->_M_parent; 245 _Rb_tree_rotate_right(__x, __root); 246 } 247 __x->_M_parent->_M_color = _S_black; 248 __xpp->_M_color = _S_red; 249 _Rb_tree_rotate_left(__xpp, __root); 250 } 251 } 252 } 253 __root->_M_color = _S_black; 254 } 255 256 _Rb_tree_node_base* 257 _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z, 258 _Rb_tree_node_base& __header) 259 { 260 _Rb_tree_node_base *& __root = __header._M_parent; 261 _Rb_tree_node_base *& __leftmost = __header._M_left; 262 _Rb_tree_node_base *& __rightmost = __header._M_right; 263 _Rb_tree_node_base* __y = __z; 264 _Rb_tree_node_base* __x = 0; 265 _Rb_tree_node_base* __x_parent = 0; 266 267 if (__y->_M_left == 0) // __z has at most one non-null child. y == z. 268 __x = __y->_M_right; // __x might be null. 269 else 270 if (__y->_M_right == 0) // __z has exactly one non-null child. y == z. 271 __x = __y->_M_left; // __x is not null. 272 else 273 { 274 // __z has two non-null children. Set __y to 275 __y = __y->_M_right; // __z's successor. __x might be null. 276 while (__y->_M_left != 0) 277 __y = __y->_M_left; 278 __x = __y->_M_right; 279 } 280 if (__y != __z) 281 { 282 // relink y in place of z. y is z's successor 283 __z->_M_left->_M_parent = __y; 284 __y->_M_left = __z->_M_left; 285 if (__y != __z->_M_right) 286 { 287 __x_parent = __y->_M_parent; 288 if (__x) __x->_M_parent = __y->_M_parent; 289 __y->_M_parent->_M_left = __x; // __y must be a child of _M_left 290 __y->_M_right = __z->_M_right; 291 __z->_M_right->_M_parent = __y; 292 } 293 else 294 __x_parent = __y; 295 if (__root == __z) 296 __root = __y; 297 else if (__z->_M_parent->_M_left == __z) 298 __z->_M_parent->_M_left = __y; 299 else 300 __z->_M_parent->_M_right = __y; 301 __y->_M_parent = __z->_M_parent; 302 std::swap(__y->_M_color, __z->_M_color); 303 __y = __z; 304 // __y now points to node to be actually deleted 305 } 306 else 307 { // __y == __z 308 __x_parent = __y->_M_parent; 309 if (__x) 310 __x->_M_parent = __y->_M_parent; 311 if (__root == __z) 312 __root = __x; 313 else 314 if (__z->_M_parent->_M_left == __z) 315 __z->_M_parent->_M_left = __x; 316 else 317 __z->_M_parent->_M_right = __x; 318 if (__leftmost == __z) 319 if (__z->_M_right == 0) // __z->_M_left must be null also 320 __leftmost = __z->_M_parent; 321 // makes __leftmost == _M_header if __z == __root 322 else 323 __leftmost = _Rb_tree_node_base::_S_minimum(__x); 324 if (__rightmost == __z) 325 if (__z->_M_left == 0) // __z->_M_right must be null also 326 __rightmost = __z->_M_parent; 327 // makes __rightmost == _M_header if __z == __root 328 else // __x == __z->_M_left 329 __rightmost = _Rb_tree_node_base::_S_maximum(__x); 330 } 331 if (__y->_M_color != _S_red) 332 { 333 while (__x != __root && (__x == 0 || __x->_M_color == _S_black)) 334 if (__x == __x_parent->_M_left) 335 { 336 _Rb_tree_node_base* __w = __x_parent->_M_right; 337 if (__w->_M_color == _S_red) 338 { 339 __w->_M_color = _S_black; 340 __x_parent->_M_color = _S_red; 341 _Rb_tree_rotate_left(__x_parent, __root); 342 __w = __x_parent->_M_right; 343 } 344 if ((__w->_M_left == 0 || 345 __w->_M_left->_M_color == _S_black) && 346 (__w->_M_right == 0 || 347 __w->_M_right->_M_color == _S_black)) 348 { 349 __w->_M_color = _S_red; 350 __x = __x_parent; 351 __x_parent = __x_parent->_M_parent; 352 } 353 else 354 { 355 if (__w->_M_right == 0 356 || __w->_M_right->_M_color == _S_black) 357 { 358 __w->_M_left->_M_color = _S_black; 359 __w->_M_color = _S_red; 360 _Rb_tree_rotate_right(__w, __root); 361 __w = __x_parent->_M_right; 362 } 363 __w->_M_color = __x_parent->_M_color; 364 __x_parent->_M_color = _S_black; 365 if (__w->_M_right) 366 __w->_M_right->_M_color = _S_black; 367 _Rb_tree_rotate_left(__x_parent, __root); 368 break; 369 } 370 } 371 else 372 { 373 // same as above, with _M_right <-> _M_left. 374 _Rb_tree_node_base* __w = __x_parent->_M_left; 375 if (__w->_M_color == _S_red) 376 { 377 __w->_M_color = _S_black; 378 __x_parent->_M_color = _S_red; 379 _Rb_tree_rotate_right(__x_parent, __root); 380 __w = __x_parent->_M_left; 381 } 382 if ((__w->_M_right == 0 || 383 __w->_M_right->_M_color == _S_black) && 384 (__w->_M_left == 0 || 385 __w->_M_left->_M_color == _S_black)) 386 { 387 __w->_M_color = _S_red; 388 __x = __x_parent; 389 __x_parent = __x_parent->_M_parent; 390 } 391 else 392 { 393 if (__w->_M_left == 0 || __w->_M_left->_M_color == _S_black) 394 { 395 __w->_M_right->_M_color = _S_black; 396 __w->_M_color = _S_red; 397 _Rb_tree_rotate_left(__w, __root); 398 __w = __x_parent->_M_left; 399 } 400 __w->_M_color = __x_parent->_M_color; 401 __x_parent->_M_color = _S_black; 402 if (__w->_M_left) 403 __w->_M_left->_M_color = _S_black; 404 _Rb_tree_rotate_right(__x_parent, __root); 405 break; 406 } 407 } 408 if (__x) __x->_M_color = _S_black; 409 } 410 return __y; 411 } 412 413 unsigned int 414 _Rb_tree_black_count(const _Rb_tree_node_base* __node, 415 const _Rb_tree_node_base* __root) 416 { 417 if (__node == 0) 418 return 0; 419 unsigned int __sum = 0; 420 do 421 { 422 if (__node->_M_color == _S_black) 423 ++__sum; 424 if (__node == __root) 425 break; 426 __node = __node->_M_parent; 427 } 428 while (1); 429 return __sum; 430 } 431 432 _GLIBCXX_END_NAMESPACE 433