private void RotateRight(RBNodeBase node) { RBNodeBase p = node; RBNodeBase q = node.Left; RBNodeBase parent = p.Parent; if (parent) { if (parent.Left == p) { parent.Left = q; } else { parent.Right = q; } } else { Root = q; } q.Parent = parent; p.Parent = q; p.Left = q.Right; if (p.Left) { p.Left.Parent = p; } q.Right = p; }
public void GetEqualOrLessTest4() { RedBlackTree tree = new RedBlackTree(); tree.RB_Insert(new TestObjectForEqualOrMore("zhu0", 0)); tree.RB_Insert(new TestObjectForEqualOrMore("zhu1", 1)); tree.RB_Insert(new TestObjectForEqualOrMore("zhu1", 1)); tree.RB_Insert(new TestObjectForEqualOrMore("zhu1", 1)); tree.RB_Insert(new TestObjectForEqualOrMore("zhu1", 1)); tree.RB_Insert(new TestObjectForEqualOrMore("zhu1", 1)); tree.RB_Insert(new TestObjectForEqualOrMore("zhu1", 1)); tree.RB_Insert(new TestObjectForEqualOrMore("zhu2", 2)); RBNodeBase node = tree.GetEqualOrLess(new TestObjectForEqualOrMore("zhu1", 1)); ValuesTest(node, "zhu1", 1); node = tree.GetNext(node); ValuesTest(node, "zhu1", 1); node = tree.GetNext(node); ValuesTest(node, "zhu1", 1); node = tree.GetNext(node); ValuesTest(node, "zhu1", 1); node = tree.GetNext(node); ValuesTest(node, "zhu1", 1); node = tree.GetNext(node); ValuesTest(node, "zhu1", 1); node = tree.GetNext(node); ValuesTest(node, "zhu2", 2); }
public RBNodeBase GetLast(RBNodeBase node) { while (node.Right) { node = node.Right; } return(node); }
public RBNodeBase GetFirst(RBNodeBase node) { while (node.Left) { node = node.Left; } return(node); }
public RBNodeBase() { this.Parent = null; this.Prev = null; this.Next = null; this.Left = null; this.Right = null; this.Red = false; }
public void TestForStableSort() { RedBlackTree tree = new RedBlackTree(new Comp()); int count = 0; for (int i = 0; i < 100000; i++) { tree.RB_Insert(new TestSortObject(count++, 0)); tree.RB_Insert(new TestSortObject(count++, 1)); tree.RB_Insert(new TestSortObject(count++, 2)); } for (int i = 0; i < 100000; i++) { RBNodeBase node = tree.GetMinimumNode(); Assert.AreEqual(i * 3, ((TestSortObject)node.Key)._index); Assert.AreEqual(0, ((TestSortObject)node.Key)._value); tree.RB_Delete(node); } for (int i = 0; i < 100000; i++) { RBNodeBase node = tree.GetMinimumNode(); Assert.AreEqual(i * 3 + 1, ((TestSortObject)node.Key)._index); Assert.AreEqual(1, ((TestSortObject)node.Key)._value); tree.RB_Delete(node); } for (int i = 0; i < 100000; i++) { RBNodeBase node = tree.GetMinimumNode(); Assert.AreEqual(i * 3 + 2, ((TestSortObject)node.Key)._index); Assert.AreEqual(2, ((TestSortObject)node.Key)._value); tree.RB_Delete(node); } /* * for ( int i = 0; i < 20; i++ ) * { * RBNode node = tree.GetMinimumNode(); * Debug.WriteLine( ((TestSortObject)node.Key)._index ); * //Assert.AreEqual( i, 199999 - ((TestSortObject)node.Key)._index ); * tree.RB_Delete( node ); * }*/ }
/// <summary> /// Performs stable sort of children using the specified comparer. /// </summary> /// <param name="comparer">The comparer used for sorting.</param> internal void SortChildren(IComparer comparer) { if (_children != null && _children.Count > 0) { lock ( _children ) { RedBlackTree tree = new RedBlackTree(comparer); for (int i = 0; i < _children.Count; i++) { tree.RB_Insert(_children [i]); } RBNodeBase node = tree.GetMinimumNode(); for (int i = 0; i < _children.Count; i++) { _children [i] = node.Key; node = tree.GetNext(node); } } } }
private void StableSort() { IntArrayList badResourceIds = null; RedBlackTree tree = new RedBlackTree(_lastComparer); for (int i = 0; i < _list.Count; i++) { IResource res = MyPalStorage.Storage.TryLoadResource(_list [i]); if (res != null) { tree.RB_Insert(res); } else { if (badResourceIds == null) { badResourceIds = new IntArrayList(); } badResourceIds.Add(_list [i]); } } RBNodeBase node = tree.GetMinimumNode(); int destIndex = 0; while (node != null) { _list [destIndex++] = ((IResource)node.Key).Id; node = tree.GetNext(node); } if (badResourceIds != null) { for (int j = 0; j < badResourceIds.Count; j++) { _list [destIndex++] = badResourceIds [j]; } } }
public void GetNextAndPreviousTest() { RedBlackTree tree = new RedBlackTree(); tree.RB_Insert(new TestObjectForEqualOrMore("zhu0", 0)); tree.RB_Insert(new TestObjectForEqualOrMore("zhu2", 2)); tree.RB_Insert(new TestObjectForEqualOrMore("zhu1", 1)); tree.RB_Insert(new TestObjectForEqualOrMore("zhu3", 3)); RBNodeBase node = tree.GetEqualOrMore(new TestObjectForEqualOrMore("zhu0", 0), null); ValuesTest(node, "zhu0", 0); node = tree.GetNext(node); ValuesTest(node, "zhu1", 1); node = tree.GetNext(node); ValuesTest(node, "zhu2", 2); node = tree.GetNext(node); ValuesTest(node, "zhu3", 3); RBNodeBase nullNode = tree.GetNext(node); Assert.AreEqual(null, nullNode); node = tree.GetPrevious(node); ValuesTest(node, "zhu2", 2); node = tree.GetPrevious(node); ValuesTest(node, "zhu1", 1); node = tree.GetPrevious(node); ValuesTest(node, "zhu0", 0); nullNode = tree.GetPrevious(node); Assert.AreEqual(null, nullNode); }
private void ValuesTest(RBNodeBase node, string str, int num) { Assert.AreEqual(str, ((TestObjectForEqualOrMore)node.Key).Str); Assert.AreEqual(num, ((TestObjectForEqualOrMore)node.Key).Num); }
public void Insert(RBNodeBase node, RBNodeBase successor) { RBNodeBase parent = null; if (node) { // >>> rhill 2011-05-27: Performance: cache previous/next nodes successor.Prev = node; successor.Next = node.Next; if (node.Next) { node.Next.Prev = successor; } node.Next = successor; // <<< if (node.Right) { // in-place expansion of node.rbRight.getFirst(); node = node.Right; while (node.Left) { node = node.Left; } node.Left = successor; } else { node.Right = successor; } parent = node; } // rhill 2011-06-07: if node is null, successor must be inserted // to the left-most part of the tree else if (Root) { node = GetFirst(Root); // >>> Performance: cache previous/next nodes successor.Prev = null; successor.Next = node; node.Prev = successor; // <<< node.Left = successor; parent = node; } else { // >>> Performance: cache previous/next nodes successor.Prev = null; successor.Next = null; // <<< Root = successor; parent = null; } successor.Left = null; successor.Right = null; successor.Parent = parent; successor.Red = true; // Fixup the modified tree by recoloring nodes and performing // rotations (2 at most) hence the red-black tree properties are // preserved. RBNodeBase grandpa; RBNodeBase uncle; node = successor; while (parent != null && parent.Red) { grandpa = parent.Parent; if (parent == grandpa.Left) { uncle = grandpa.Right; if (uncle != null && uncle.Red) { parent.Red = false; uncle.Red = false; grandpa.Red = true; node = grandpa; } else { if (node == parent.Right) { RotateLeft(parent); node = parent; parent = node.Parent; } parent.Red = false; grandpa.Red = true; RotateRight(grandpa); } } else { uncle = grandpa.Left; if (uncle != null && uncle.Red) { parent.Red = false; uncle.Red = false; grandpa.Red = true; node = grandpa; } else { if (node == parent.Left) { RotateRight(parent); node = parent; parent = node.Parent; } parent.Red = false; grandpa.Red = true; RotateLeft(grandpa); } } parent = node.Parent; } Root.Red = false; }
public RBTree() { this.Root = null; }
public void Remove(RBNodeBase node) { // >>> rhill 2011-05-27: Performance: cache previous/next nodes if (node.Next) { node.Next.Prev = node.Prev; } if (node.Prev) { node.Prev.Next = node.Next; } node.Next = null; node.Prev = null; // <<< RBNodeBase parent = node.Parent; RBNodeBase left = node.Left; RBNodeBase right = node.Right; RBNodeBase next = (left == null) ? right : (right == null) ? left : GetFirst(right); if (parent) { if (parent.Left == node) { parent.Left = next; } else { parent.Right = next; } } else { Root = next; } // rhill - enforce red-black rules bool isRed; if (left && right) { isRed = next.Red; next.Red = node.Red; next.Left = left; left.Parent = next; if (next != right) { parent = next.Parent; next.Parent = node.Parent; node = next.Right; parent.Left = node; next.Right = right; right.Parent = next; } else { next.Parent = parent; parent = next; node = next.Right; } } else { isRed = node.Red; node = next; } // 'node' is now the sole successor's child and 'parent' its // new parent (since the successor can have been moved) if (node) { node.Parent = parent; } // the 'easy' cases if (isRed) { return; } if (node != null && node.Red) { node.Red = false; return; } // the other cases RBNodeBase sibling; do { if (node == Root) { break; } if (node == parent.Left) { sibling = parent.Right; if (sibling.Red) { sibling.Red = false; parent.Red = true; RotateLeft(parent); sibling = parent.Right; } if ((sibling.Left != null && sibling.Left.Red) || (sibling.Right != null && sibling.Right.Red)) { if (sibling.Right == null || !sibling.Right.Red) { sibling.Left.Red = false; sibling.Red = true; RotateRight(sibling); sibling = parent.Right; } sibling.Red = parent.Red; parent.Red = false; sibling.Right.Red = false; RotateLeft(parent); node = Root; break; } } else { sibling = parent.Left; if (sibling.Red) { sibling.Red = false; parent.Red = true; RotateRight(parent); sibling = parent.Left; } if ((sibling.Left != null && sibling.Left.Red) || (sibling.Right != null && sibling.Right.Red)) { if (sibling.Left == null || !sibling.Left.Red) { sibling.Right.Red = false; sibling.Red = true; RotateLeft(sibling); sibling = parent.Left; } sibling.Red = parent.Red; parent.Red = false; sibling.Left.Red = false; RotateRight(parent); node = Root; break; } } sibling.Red = true; node = parent; parent = parent.Parent; }while (!node.Red); if (node) { node.Red = false; } }