001/* 002 File: RBCell.java 003 004 Originally written by Doug Lea and released into the public domain. 005 Thanks for the assistance and support of Sun Microsystems Labs, Agorics 006 Inc, Loral, and everyone contributing, testing, and using this code. 007 008 History: 009 Date Who What 010 24Sep95 dl@cs.oswego.edu Create from collections.java working file 011 012*/ 013package cnslab.cnsmath; 014import java.util.Enumeration; 015import java.util.NoSuchElementException; 016 017/** 018 * RBCell implements basic capabilities of Red-Black trees, 019 * an efficient kind of balanced binary tree. The particular 020 * algorithms used are adaptations of those in Corman, 021 * Lieserson, and Rivest's <EM>Introduction to Algorithms</EM>. 022 * This class was inspired by (and code cross-checked with) a 023 * similar class by Chuck McManis. The implementations of 024 * rebalancings during insertion and deletion are 025 * a little trickier than those versions since they 026 * don't swap cell contents or use a special dummy nilnodes. 027 * <P> 028 * It is a pure implementation class. For harnesses, see: 029 * @see RBTree 030 * @author Doug Lea 031 * @version 0.93 032 * 033 * <P> For an introduction to this package see <A HREF="index.html"> Overview </A>. 034 * 035**/ 036 037 038 039 040public class RBCell<T extends Comparable> extends Cell<T> { 041 static final boolean RED = false; 042 static final boolean BLACK = true; 043 044/** 045 * The node color (RED, BLACK) 046**/ 047 048 protected boolean color_; 049 050/** 051 * Pointer to left child 052**/ 053 054 protected RBCell left_; 055 056/** 057 * Pointer to right child 058**/ 059 060 protected RBCell right_; 061 062/** 063 * Pointer to parent (null if root) 064**/ 065 066 private RBCell parent_; 067 068/** 069 * Make a new cell with given element, null links, and BLACK color. 070 * Normally only called to establish a new root. 071**/ 072 073 public RBCell(T element) { 074 super(element); 075 left_ = null; right_ = null; parent_ = null; color_ = BLACK; 076 } 077 078 079/** 080 * Return left child (or null) 081**/ 082 083 public final RBCell left() { return left_; } 084 085/** 086 * Return right child (or null) 087**/ 088 089 public final RBCell right() { return right_; } 090 091/** 092 * Return parent (or null) 093**/ 094 public final RBCell parent() { return parent_; } 095 096 097/** 098 * @see collections.ImplementationCheckable.checkImplementation. 099**/ 100 /* 101 public void checkImplementation() { 102 103 // It's too hard to check the property that every simple 104 // path from node to leaf has same number of black nodes. 105 // So restrict to the following 106 107 assertt(parent_ == null || 108 this == parent_.left_ || 109 this == parent_.right_); 110 111 assertt(left_ == null || 112 this == left_.parent_); 113 114 assertt(right_ == null || 115 this == right_.parent_); 116 117 assertt(color_ == BLACK || 118 (colorOf(left_) == BLACK) && (colorOf(right_) == BLACK)); 119 120 if (left_ != null) left_.checkImplementation(); 121 if (right_ != null) right_.checkImplementation(); 122 } 123 */ 124 125/** 126 * Return the minimum element of the current (sub)tree 127**/ 128 129 public final RBCell leftmost() { 130 RBCell p = this; 131 for ( ; p.left_ != null; p = p.left_) {} 132 return p; 133 } 134 135/** 136 * Return the maximum element of the current (sub)tree 137**/ 138 public final RBCell rightmost() { 139 RBCell p = this; 140 for ( ; p.right_ != null; p = p.right_) {} 141 return p; 142 } 143 144/** 145 * Return the root (parentless node) of the tree 146**/ 147 public final RBCell root() { 148 RBCell p = this; 149 for ( ; p.parent_ != null; p = p.parent_) {} 150 return p; 151 } 152 153/** 154 * Return true if node is a root (i.e., has a null parent) 155**/ 156 157 public final boolean isRoot() { return parent_ == null; } 158 159 160/** 161 * Return the inorder successor, or null if no such 162**/ 163 164 public final RBCell<T> successor() { 165 if (right_ != null) 166 return right_.leftmost(); 167 else { 168 RBCell p = parent_; 169 RBCell ch = this; 170 while (p != null && ch == p.right_) { ch = p; p = p.parent_; } 171 return p; 172 } 173 } 174 175/** 176 * Return the inorder predecessor, or null if no such 177**/ 178 179 public final RBCell<T> predecessor() { 180 if (left_ != null) 181 return left_.rightmost(); 182 else { 183 RBCell p = parent_; 184 RBCell ch = this; 185 while (p != null && ch == p.left_) { ch = p; p = p.parent_; } 186 return p; 187 } 188 } 189 190/** 191 * Return the number of nodes in the subtree 192**/ 193 public final int size() { 194 int c = 1; 195 if (left_ != null) c += left_.size(); 196 if (right_ != null) c += right_.size(); 197 return c; 198 } 199 200 201/** 202 * Return node of current subtree containing element as element(), 203 * if it exists, else null. 204 * Uses Comparator cmp to find and to check equality. 205**/ 206 207 public RBCell find(T element) { 208 RBCell t = this; 209 for (;;) { 210 int diff = element.compareTo(t.element()); 211 if (diff == 0) return t; 212 else if (diff < 0) t = t.left_; 213 else t = t.right_; 214 if (t == null) return null; 215 } 216 } 217 218 219/** 220 * Return number of nodes of current subtree containing element. 221 * Uses Comparator cmp to find and to check equality. 222**/ 223 public int count(T element) { 224 int c = 0; 225 RBCell t = this; 226 while (t != null) { 227 int diff = element.compareTo(t.element()); 228 if (diff == 0) { 229 ++c; 230 if (t.left_ == null) 231 t = t.right_; 232 else if (t.right_ == null) 233 t = t.left_; 234 else { 235 c += t.right_.count(element); 236 t = t.left_; 237 } 238 } 239 else if (diff < 0) t = t.left_; 240 else t = t.right_; 241 } 242 return c; 243 } 244 245 246 247 248 249/** 250 * There's no generic element insertion. Instead find the 251 * place you want to add a node and then invoke insertLeft 252 * or insertRight. 253 * <P> 254 * Insert cell as the left child of current node, and then 255 * rebalance the tree it is in. 256 * @param cell the cell to add 257 * @param root, the root of the current tree 258 * @return the new root of the current tree. (Rebalancing 259 * can change the root!) 260**/ 261 262 263 public RBCell insertLeft(RBCell cell, RBCell root) { 264 left_ = cell; 265 cell.parent_ = this; 266 return cell.fixAfterInsertion(root); 267 } 268 269/** 270 * Insert cell as the right child of current node, and then 271 * rebalance the tree it is in. 272 * @param cell the cell to add 273 * @param root, the root of the current tree 274 * @return the new root of the current tree. (Rebalancing 275 * can change the root!) 276**/ 277 278 public RBCell insertRight(RBCell cell, RBCell root) { 279 right_ = cell; 280 cell.parent_ = this; 281 return cell.fixAfterInsertion(root); 282 } 283 284 285/** 286 * Delete the current node, and then rebalance the tree it is in 287 * @param root the root of the current tree 288 * @return the new root of the current tree. (Rebalancing 289 * can change the root!) 290**/ 291 292 293 public RBCell delete(RBCell root) { 294 295 // handle case where we are only node 296 if (left_ == null && right_ == null && parent_ == null) return null; 297 298 // if strictly internal, swap places with a successor 299 if (left_ != null && right_ != null) { 300 RBCell s = successor(); 301 // To work nicely with arbitrary subclasses of RBCell, we don't want to 302 // just copy successor's fields. since we don't know what 303 // they are. Instead we swap positions in the tree. 304 root = swapPosition(this, s, root); 305 } 306 307 // Start fixup at replacement node (normally a child). 308 // But if no children, fake it by using self 309 310 if (left_ == null && right_ == null) { 311 312 if (color_ == BLACK) 313 root = this.fixAfterDeletion(root); 314 315 // Unlink (Couldn't before since fixAfterDeletion needs parent ptr) 316 317 if (parent_ != null) { 318 if (this == parent_.left_) 319 parent_.left_ = null; 320 else if (this == parent_.right_) 321 parent_.right_ = null; 322 parent_ = null; 323 } 324 325 } 326 else { 327 RBCell replacement = left_; 328 if (replacement == null) replacement = right_; 329 330 // link replacement to parent 331 replacement.parent_ = parent_; 332 333 if (parent_ == null) root = replacement; 334 else if (this == parent_.left_) parent_.left_ = replacement; 335 else parent_.right_ = replacement; 336 337 left_ = null; 338 right_ = null; 339 parent_ = null; 340 341 // fix replacement 342 if (color_ == BLACK) 343 root = replacement.fixAfterDeletion(root); 344 345 } 346 347 return root; 348 } 349 350/** 351 * Swap the linkages of two nodes in a tree. 352 * Return new root, in case it changed. 353**/ 354 355 static RBCell swapPosition(RBCell x, RBCell y, RBCell root) { 356 357 /* Too messy. TODO: find sequence of assigments that are always OK */ 358 359 RBCell px = x.parent_; 360 boolean xpl = px != null && x == px.left_; 361 RBCell lx = x.left_; 362 RBCell rx = x.right_; 363 364 RBCell py = y.parent_; 365 boolean ypl = py != null && y == py.left_; 366 RBCell ly = y.left_; 367 RBCell ry = y.right_; 368 369 if (x == py) { 370 y.parent_ = px; 371 if (px != null) if (xpl) px.left_ = y; else px.right_ = y; 372 x.parent_ = y; 373 if (ypl) { 374 y.left_ = x; 375 y.right_ = rx; if (rx != null) rx.parent_ = y; 376 } 377 else { 378 y.right_ = x; 379 y.left_ = lx; if (lx != null) lx.parent_ = y; 380 } 381 x.left_ = ly; if (ly != null) ly.parent_ = x; 382 x.right_ = ry; if (ry != null) ry.parent_ = x; 383 } 384 else if (y == px) { 385 x.parent_ = py; 386 if (py != null) if (ypl) py.left_ = x; else py.right_ = x; 387 y.parent_ = x; 388 if (xpl) { 389 x.left_ = y; 390 x.right_ = ry; if (ry != null) ry.parent_ = x; 391 } 392 else { 393 x.right_ = y; 394 x.left_ = ly; if (ly != null) ly.parent_ = x; 395 } 396 y.left_ = lx; if (lx != null) lx.parent_ = y; 397 y.right_ = rx; if (rx != null) rx.parent_ = y; 398 } 399 else { 400 x.parent_ = py; if (py != null) if (ypl) py.left_ = x; else py.right_ = x; 401 x.left_ = ly; if (ly != null) ly.parent_ = x; 402 x.right_ = ry; if (ry != null) ry.parent_ = x; 403 404 y.parent_ = px; if (px != null) if (xpl) px.left_ = y; else px.right_ = y; 405 y.left_ = lx; if (lx != null) lx.parent_ = y; 406 y.right_ = rx; if (rx != null) rx.parent_ = y; 407 } 408 409 boolean c = x.color_; x.color_ = y.color_; y.color_ = c; 410 411 if (root == x) root = y; 412 else if (root == y) root = x; 413 return root; 414 } 415 416 417 418/** 419 * Return color of node p, or BLACK if p is null 420 * (In the CLR version, they use 421 * a special dummy `nil' node for such purposes, but that doesn't 422 * work well here, since it could lead to creating one such special 423 * node per real node.) 424 * 425**/ 426 427 static boolean colorOf(RBCell p) { return (p == null)? BLACK : p.color_; } 428 429/** 430 * return parent of node p, or null if p is null 431**/ 432 static RBCell parentOf(RBCell p) { return (p == null)? null: p.parent_; } 433 434/** 435 * Set the color of node p, or do nothing if p is null 436**/ 437 438 static void setColor(RBCell p, boolean c) { if (p != null) p.color_ = c; } 439 440/** 441 * return left child of node p, or null if p is null 442**/ 443 444 static RBCell leftOf(RBCell p) { return (p == null)? null: p.left_; } 445 446/** 447 * return right child of node p, or null if p is null 448**/ 449 450 static RBCell rightOf(RBCell p) { return (p == null)? null: p.right_; } 451 452 /** 453 * Searches a node with smallest key starting from the node x which is usually the root. 454 * Runs in O(h) time where h is the height of the tree. 455 * 456 * @param x The node from which to start, usually the root. 457 * @return The node with the smallest key. 458 * @throws NullPointerException If the parameter x is null. 459 */ 460 public RBCell<T> treeMinimum() 461 { 462 while (this.left() != null) 463 { 464 this.treeMinimum(); 465 } 466 return this; 467 } 468 469 public RBCell<T> treeMaximum() 470 { 471 while (this.right() != null) 472 { 473 this.treeMaximum(); 474 } 475 return this; 476 } 477 478 479 480 /** From CLR **/ 481 protected final RBCell rotateLeft(RBCell root) { 482 RBCell r = right_; 483 right_ = r.left_; 484 if (r.left_ != null) r.left_.parent_ = this; 485 r.parent_ = parent_; 486 if (parent_ == null) root = r; 487 else if (parent_.left_ == this) parent_.left_ = r; 488 else parent_.right_ = r; 489 r.left_ = this; 490 parent_ = r; 491 return root; 492 } 493 494 /** From CLR **/ 495 protected final RBCell rotateRight(RBCell root) { 496 RBCell l = left_; 497 left_ = l.right_; 498 if (l.right_ != null) l.right_.parent_ = this; 499 l.parent_ = parent_; 500 if (parent_ == null) root = l; 501 else if (parent_.right_ == this) parent_.right_ = l; 502 else parent_.left_ = l; 503 l.right_ = this; 504 parent_ = l; 505 return root; 506 } 507 508 509 /** From CLR **/ 510 protected final RBCell fixAfterInsertion(RBCell root) { 511 color_ = RED; 512 RBCell x = this; 513 514 while (x != null && x != root && x.parent_.color_ == RED) { 515 if (parentOf(x) == leftOf(parentOf(parentOf(x)))) { 516 RBCell y = rightOf(parentOf(parentOf(x))); 517 if (colorOf(y) == RED) { 518 setColor(parentOf(x), BLACK); 519 setColor(y, BLACK); 520 setColor(parentOf(parentOf(x)), RED); 521 x = parentOf(parentOf(x)); 522 } 523 else { 524 if (x == rightOf(parentOf(x))) { 525 x = parentOf(x); 526 root = x.rotateLeft(root); 527 } 528 setColor(parentOf(x), BLACK); 529 setColor(parentOf(parentOf(x)), RED); 530 if (parentOf(parentOf(x)) != null) 531 root = parentOf(parentOf(x)).rotateRight(root); 532 } 533 } 534 else { 535 RBCell y = leftOf(parentOf(parentOf(x))); 536 if (colorOf(y) == RED) { 537 setColor(parentOf(x), BLACK); 538 setColor(y, BLACK); 539 setColor(parentOf(parentOf(x)), RED); 540 x = parentOf(parentOf(x)); 541 } 542 else { 543 if (x == leftOf(parentOf(x))) { 544 x = parentOf(x); 545 root = x.rotateRight(root); 546 } 547 setColor(parentOf(x), BLACK); 548 setColor(parentOf(parentOf(x)), RED); 549 if (parentOf(parentOf(x)) != null) 550 root = parentOf(parentOf(x)).rotateLeft(root); 551 } 552 } 553 } 554 root.color_ = BLACK; 555 return root; 556 } 557 558 559 560 /** From CLR **/ 561 protected final RBCell fixAfterDeletion(RBCell root) { 562 RBCell x = this; 563 while (x != root && colorOf(x) == BLACK) { 564 if (x == leftOf(parentOf(x))) { 565 RBCell sib = rightOf(parentOf(x)); 566 if (colorOf(sib) == RED) { 567 setColor(sib, BLACK); 568 setColor(parentOf(x), RED); 569 root = parentOf(x).rotateLeft(root); 570 sib = rightOf(parentOf(x)); 571 } 572 if (colorOf(leftOf(sib)) == BLACK && colorOf(rightOf(sib)) == BLACK) { 573 setColor(sib, RED); 574 x = parentOf(x); 575 } 576 else { 577 if (colorOf(rightOf(sib)) == BLACK) { 578 setColor(leftOf(sib), BLACK); 579 setColor(sib, RED); 580 root = sib.rotateRight(root); 581 sib = rightOf(parentOf(x)); 582 } 583 setColor(sib, colorOf(parentOf(x))); 584 setColor(parentOf(x), BLACK); 585 setColor(rightOf(sib), BLACK); 586 root = parentOf(x).rotateLeft(root); 587 x = root; 588 } 589 } 590 else { 591 RBCell sib = leftOf(parentOf(x)); 592 if (colorOf(sib) == RED) { 593 setColor(sib, BLACK); 594 setColor(parentOf(x), RED); 595 root = parentOf(x).rotateRight(root); 596 sib = leftOf(parentOf(x)); 597 } 598 if (colorOf(rightOf(sib)) == BLACK && colorOf(leftOf(sib)) == BLACK) { 599 setColor(sib, RED); 600 x = parentOf(x); 601 } 602 else { 603 if (colorOf(leftOf(sib)) == BLACK) { 604 setColor(rightOf(sib), BLACK); 605 setColor(sib, RED); 606 root = sib.rotateLeft(root); 607 sib = leftOf(parentOf(x)); 608 } 609 setColor(sib, colorOf(parentOf(x))); 610 setColor(parentOf(x), BLACK); 611 setColor(leftOf(sib), BLACK); 612 root = parentOf(x).rotateRight(root); 613 x = root; 614 } 615 } 616 } 617 setColor(x, BLACK); 618 return root; 619 } 620 621}