Skip to content

Commit 3b8c475

Browse files
Fix PR suggestions, add more test for case when node without children is removed, fix condition when removing last node.
1 parent a8a8331 commit 3b8c475

File tree

2 files changed

+55
-8
lines changed

2 files changed

+55
-8
lines changed

DataStructures/Trees/RedBlackTree.cs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ public enum RedBlackTreeColors
1313
Black = 1
1414
};
1515

16-
1716
/// <summary>
1817
/// Red-Black Tree Data Structure.
1918
/// </summary>
@@ -28,6 +27,10 @@ public class RedBlackTree<TKey> : BinarySearchTree<TKey> where TKey : IComparabl
2827
internal set { base.Root = value; }
2928
}
3029

30+
private bool IsRoot(RedBlackTreeNode<TKey> node)
31+
{
32+
return node == this.Root;
33+
}
3134

3235
/// <summary>
3336
/// CONSTRUCTOR.
@@ -465,16 +468,21 @@ protected bool _remove(RedBlackTreeNode<TKey> nodeToDelete)
465468
return false;
466469
}
467470

468-
if (!nodeToDelete.HasChildren)
471+
if (IsRoot(nodeToDelete) && !nodeToDelete.HasChildren)
469472
{
470473
Root = null;
471474
}
472475
else
473476
{
474-
// X it's node that will become move to original nodeToDelete position in the tree.
477+
// X is the node we will replace with the nodeToDelete in the tree once we remove it.
475478
RedBlackTreeNode<TKey> x;
476479

477-
if (nodeToDelete.HasOnlyRightChild)
480+
if (!nodeToDelete.HasChildren)
481+
{
482+
x = nodeToDelete;
483+
Transplant(nodeToDelete, null);
484+
}
485+
else if (nodeToDelete.HasOnlyRightChild)
478486
{
479487
x = nodeToDelete.RightChild;
480488
Transplant(nodeToDelete, nodeToDelete.RightChild);
@@ -486,8 +494,8 @@ protected bool _remove(RedBlackTreeNode<TKey> nodeToDelete)
486494
}
487495
else
488496
{
489-
// Y it's node that will become move to original X position in the tree.
490-
var y = (RedBlackTreeNode<TKey>) _findMinNode(nodeToDelete.RightChild);
497+
// Y is the node we will replace with the X in the tree once we move it to the nodeToDelete position.
498+
var y = (RedBlackTreeNode<TKey>)_findMinNode(nodeToDelete.RightChild);
491499
x = y.RightChild;
492500

493501
if (y.Parent == nodeToDelete)
@@ -652,7 +660,5 @@ public override void RemoveMax()
652660
// Invoke the internal remove node method.
653661
this._remove(node);
654662
}
655-
656663
}
657-
658664
}

UnitTest/DataStructuresTests/RedBlackTreeTest.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,47 @@ public void Remove_ThrowExceptionWhenTryRemoveNonExistentNode()
375375
Assert.Throws<Exception>(() =>redBlackTree.Remove(999));
376376
}
377377

378+
/** Remove 8, (r -> red, b -> black):
379+
** 11(b) ===> 11(b)
380+
** / \ ===> / \
381+
** (r)3 13(b) ===> (r)3 13(b)
382+
** / \ \ ===> / \ \
383+
** (b)1 7(b) 15(r) ===> (b)1 7(b) 15(r)
384+
** / \ ===> /
385+
** (r)5 8(r) ===> 5(r)
386+
**/
387+
[Fact]
388+
public void Remove_NodeWithoutChildren()
389+
{
390+
redBlackTree.Remove(8);
391+
392+
RedBlackTreeRule.CheckRedBlackTreeRules(redBlackTree);
393+
394+
Assert.Equal(7, redBlackTree.Count);
395+
Assert.Equal(11, redBlackTree.Root.Value);
396+
Assert.Equal(RedBlackTreeColors.Black, redBlackTree.Root.Color);
397+
398+
Assert.Equal(3, redBlackTree.Root.LeftChild.Value);
399+
Assert.Equal(RedBlackTreeColors.Red, redBlackTree.Root.LeftChild.Color);
400+
401+
Assert.Equal(1, redBlackTree.Root.LeftChild.LeftChild.Value);
402+
Assert.Equal(RedBlackTreeColors.Black, redBlackTree.Root.LeftChild.LeftChild.Color);
403+
404+
Assert.Equal(7, redBlackTree.Root.LeftChild.RightChild.Value);
405+
Assert.Equal(RedBlackTreeColors.Black, redBlackTree.Root.LeftChild.RightChild.Color);
406+
407+
Assert.Equal(5, redBlackTree.Root.LeftChild.RightChild.LeftChild.Value);
408+
Assert.Equal(RedBlackTreeColors.Red, redBlackTree.Root.LeftChild.RightChild.LeftChild.Color);
409+
410+
Assert.Null(redBlackTree.Root.LeftChild.RightChild.RightChild);
411+
412+
Assert.Equal(13, redBlackTree.Root.RightChild.Value);
413+
Assert.Equal(RedBlackTreeColors.Black, redBlackTree.Root.RightChild.Color);
414+
415+
Assert.Equal(15, redBlackTree.Root.RightChild.RightChild.Value);
416+
Assert.Equal(RedBlackTreeColors.Red, redBlackTree.Root.RightChild.RightChild.Color);
417+
}
418+
378419
[Fact]
379420
public void Remove_OneAndOnlyTreeNode()
380421
{

0 commit comments

Comments
 (0)