@@ -209,28 +209,26 @@ protected void removeNode(Node<T> node) {
209
209
if (lesser .id != null && greater .id != null ) {
210
210
// Two children
211
211
RedBlackNode <T > greatestInLesser = (RedBlackNode <T >) this .getGreatest (lesser );
212
- if (greatestInLesser == null || greatestInLesser .id == null )
213
- greatestInLesser = lesser ;
212
+ if (greatestInLesser == null || greatestInLesser .id == null ) greatestInLesser = lesser ;
214
213
// Replace node with greatest in his lesser tree, which leaves
215
214
// us with only one child
216
215
replaceValueOnly (nodeRemoved , greatestInLesser );
217
216
nodeRemoved = greatestInLesser ;
218
217
}
219
218
220
219
// Handle one child
221
- RedBlackNode <T > child = (RedBlackNode <T >) ((nodeRemoved .lesser .id != null ) ? nodeRemoved .lesser
222
- : nodeRemoved .greater );
220
+ RedBlackNode <T > child = (RedBlackNode <T >) ((nodeRemoved .lesser .id != null ) ? nodeRemoved .lesser : nodeRemoved .greater );
223
221
if (nodeRemoved .color == BLACK ) {
224
- if (child .color == BLACK ) {
225
- nodeRemoved .color = RED ;
226
- }
222
+ if (child .color == BLACK ) nodeRemoved .color = RED ;
227
223
boolean result = balanceAfterDelete (nodeRemoved );
228
224
if (!result ) return ;
229
225
}
230
226
replaceWithChild (nodeRemoved , child );
231
- if (root .equals (nodeRemoved ) && nodeRemoved .isLeaf ()) {
227
+ if (root .equals (nodeRemoved )) {
228
+ root .parent = null ;
229
+ ((RedBlackNode <T >)root ).color = BLACK ;
232
230
// If we replaced the root with a leaf, just null out root
233
- root = null ;
231
+ if ( nodeRemoved . isLeaf ()) root = null ;
234
232
}
235
233
}
236
234
@@ -263,12 +261,11 @@ private void replaceWithChild(RedBlackNode<T> nodeToReplace, RedBlackNode<T> nod
263
261
nodeToReplace .id = nodeToReplaceWith .id ;
264
262
nodeToReplace .color = nodeToReplaceWith .color ;
265
263
266
- // root should always be black
267
- if (nodeToReplace .parent == null )
268
- nodeToReplace .color = BLACK ;
269
-
270
264
nodeToReplace .lesser = nodeToReplaceWith .lesser ;
265
+ if (nodeToReplace .lesser !=null ) nodeToReplace .lesser .parent = nodeToReplace ;
266
+
271
267
nodeToReplace .greater = nodeToReplaceWith .greater ;
268
+ if (nodeToReplace .greater !=null ) nodeToReplace .greater .parent = nodeToReplace ;
272
269
}
273
270
274
271
/**
@@ -306,34 +303,40 @@ private boolean balanceAfterDelete(RedBlackNode<T> node) {
306
303
}
307
304
}
308
305
309
- if (parent .color == BLACK && sibling .color == BLACK && ((RedBlackNode <T >) sibling .lesser ).color == BLACK
310
- && ((RedBlackNode <T >) sibling .greater ).color == BLACK ) {
306
+ if (parent .color == BLACK && sibling .color == BLACK
307
+ && ((RedBlackNode <T >) sibling .lesser ).color == BLACK
308
+ && ((RedBlackNode <T >) sibling .greater ).color == BLACK
309
+ ) {
311
310
// Case 3 - parent, sibling, and sibling's children are black.
312
311
sibling .color = RED ;
313
312
boolean result = balanceAfterDelete (parent );
314
- if (!result )
315
- return false ;
316
- } else if ( parent . color == RED && sibling . color == BLACK && ((RedBlackNode <T >) sibling .lesser ).color == BLACK
317
- && ((RedBlackNode <T >) sibling .greater ).color == BLACK ) {
318
- // Case 4 - sibling and sibling's children are black, but parent is
319
- // red.
313
+ if (!result ) return false ;
314
+ } else if ( parent . color == RED && sibling . color == BLACK
315
+ && ((RedBlackNode <T >) sibling .lesser ).color == BLACK
316
+ && ((RedBlackNode <T >) sibling .greater ).color == BLACK
317
+ ) {
318
+ // Case 4 - sibling and sibling's children are black, but parent is red.
320
319
sibling .color = RED ;
321
320
parent .color = BLACK ;
322
321
} else {
323
322
if (sibling .color == BLACK ) {
324
323
// Case 5 - sibling is black, sibling's left child is red,
325
324
// sibling's right child is black, and node is the left child of
326
325
// its parent.
327
- if (node .equals (parent .lesser ) && ((RedBlackNode <T >) sibling .lesser ).color == RED
328
- && ((RedBlackNode <T >) sibling .greater ).color == BLACK ) {
326
+ if (node .equals (parent .lesser )
327
+ && ((RedBlackNode <T >) sibling .lesser ).color == RED
328
+ && ((RedBlackNode <T >) sibling .greater ).color == BLACK
329
+ ) {
329
330
sibling .color = RED ;
330
331
((RedBlackNode <T >) sibling .lesser ).color = RED ;
331
332
rotateRight (sibling );
332
333
// Rotation, need to update parent/sibling
333
334
parent = (RedBlackNode <T >) node .parent ;
334
335
sibling = node .getSibling ();
335
- } else if (node .equals (parent .greater ) && ((RedBlackNode <T >) sibling .lesser ).color == BLACK
336
- && ((RedBlackNode <T >) sibling .greater ).color == RED ) {
336
+ } else if (node .equals (parent .greater )
337
+ && ((RedBlackNode <T >) sibling .lesser ).color == BLACK
338
+ && ((RedBlackNode <T >) sibling .greater ).color == RED
339
+ ) {
337
340
sibling .color = RED ;
338
341
((RedBlackNode <T >) sibling .greater ).color = RED ;
339
342
rotateLeft (sibling );
@@ -393,32 +396,26 @@ protected boolean validateNode(Node<T> node) {
393
396
394
397
if (rbNode .color == RED ) {
395
398
// You should not have two red nodes in a row
396
- if (lesser .color == RED )
397
- return false ;
398
- if (greater .color == RED )
399
- return false ;
399
+ if (lesser .color == RED ) return false ;
400
+ if (greater .color == RED ) return false ;
400
401
}
401
402
402
403
if (!lesser .isLeaf ()) {
403
404
// Check BST property
404
405
boolean lesserCheck = lesser .id .compareTo (rbNode .id ) <= 0 ;
405
- if (!lesserCheck )
406
- return false ;
406
+ if (!lesserCheck ) return false ;
407
407
// Check red-black property
408
408
lesserCheck = this .validateNode (lesser );
409
- if (!lesserCheck )
410
- return false ;
409
+ if (!lesserCheck ) return false ;
411
410
}
412
411
413
412
if (!greater .isLeaf ()) {
414
413
// Check BST property
415
414
boolean greaterCheck = greater .id .compareTo (rbNode .id ) > 0 ;
416
- if (!greaterCheck )
417
- return false ;
415
+ if (!greaterCheck ) return false ;
418
416
// Check red-black property
419
417
greaterCheck = this .validateNode (greater );
420
- if (!greaterCheck )
421
- return false ;
418
+ if (!greaterCheck ) return false ;
422
419
}
423
420
424
421
return true ;
@@ -458,15 +455,13 @@ protected RedBlackNode(Node<T> parent, T id, boolean color) {
458
455
}
459
456
460
457
protected RedBlackNode <T > getGrandParent () {
461
- if (parent == null || parent .parent == null )
462
- return null ;
458
+ if (parent == null || parent .parent == null ) return null ;
463
459
return (RedBlackNode <T >) parent .parent ;
464
460
}
465
461
466
462
protected RedBlackNode <T > getUncle () {
467
463
RedBlackNode <T > grandParent = getGrandParent ();
468
- if (grandParent == null )
469
- return null ;
464
+ if (grandParent == null ) return null ;
470
465
if (grandParent .lesser != null && grandParent .lesser .equals (parent )) {
471
466
return (RedBlackNode <T >) grandParent .greater ;
472
467
} else if (grandParent .greater != null && grandParent .greater .equals (parent )) {
@@ -476,8 +471,7 @@ protected RedBlackNode<T> getUncle() {
476
471
}
477
472
478
473
protected RedBlackNode <T > getSibling () {
479
- if (parent == null )
480
- return null ;
474
+ if (parent == null ) return null ;
481
475
if (parent .lesser .equals (this )) {
482
476
return (RedBlackNode <T >) parent .greater ;
483
477
} else if (parent .greater .equals (this )) {
@@ -489,10 +483,8 @@ protected RedBlackNode<T> getSibling() {
489
483
}
490
484
491
485
protected boolean isLeaf () {
492
- if (lesser != null )
493
- return false ;
494
- if (greater != null )
495
- return false ;
486
+ if (lesser != null ) return false ;
487
+ if (greater != null ) return false ;
496
488
return true ;
497
489
}
498
490
@@ -524,8 +516,11 @@ public static <T extends Comparable<T>> String getString(RedBlackNode<T> node) {
524
516
private static <T extends Comparable <T >> String getString (RedBlackNode <T > node , String prefix , boolean isTail ) {
525
517
StringBuilder builder = new StringBuilder ();
526
518
527
- builder .append (prefix + (isTail ? "└── " : "├── " ) + "(" + ((node .color == RED ) ? "RED" : "BLACK" ) + ") "
528
- + node .id + "\n " );
519
+ builder .append (prefix + (isTail ? "└── " : "├── " ) + "(" + ((node .color == RED ) ? "RED" : "BLACK" ) + ") " + node .id
520
+ + " [parent=" + ((node .parent !=null )?node .parent .id :"NULL" )
521
+ + " grand-parent=" + ((node .parent !=null && node .parent .parent !=null )?node .parent .parent .id :"NULL" )
522
+ + "]\n "
523
+ );
529
524
List <Node <T >> children = null ;
530
525
if (node .lesser != null || node .greater != null ) {
531
526
children = new ArrayList <Node <T >>(2 );
0 commit comments