public RBTreeBase(IComparer <T> aComparer, bool unique) { this.mRoot = (RBTreeNodeBase <T, P>)null; this.mComparer = aComparer; this.mCount = 0; this.mUnique = unique; }
internal RBTreeNodeBase <T, P> Traverse(ref bool aInsert, T aKey) { RBTreeNodeBase <T, P> rbTreeNodeBase1 = (RBTreeNodeBase <T, P>)null; RBTreeNodeBase <T, P> rbTreeNodeBase2 = this.mRoot; while (rbTreeNodeBase2 != null) { rbTreeNodeBase1 = rbTreeNodeBase2; int num = this.mComparer.Compare(aKey, rbTreeNodeBase2.mKey); if (!this.mUnique && num == 0 && aInsert) { num = 1; } if (num < 0) { rbTreeNodeBase2 = rbTreeNodeBase2.mLeft; } else if (num > 0) { rbTreeNodeBase2 = rbTreeNodeBase2.mRight; } else { aInsert = false; return(rbTreeNodeBase2); } } if (!aInsert) { return((RBTreeNodeBase <T, P>)null); } RBTreeNodeBase <T, P> z = this.NewNode(); z.mKey = aKey; z.mParent = rbTreeNodeBase1; if (rbTreeNodeBase1 == null) { this.mRoot = z; } else { int num = this.mComparer.Compare(z.mKey, rbTreeNodeBase1.mKey); if (num == 0) { num = 1; } if (num < 0) { rbTreeNodeBase1.SetLeft(z); } else { rbTreeNodeBase1.SetRight(z); } } z.mColor = RBTreeColor.Red; this.Balance(z); this.mRoot.mColor = RBTreeColor.Black; return(z); }
public RBTreeBase(bool unique) { this.mRoot = (RBTreeNodeBase <T, P>)null; this.mComparer = (IComparer <T>)Comparer <T> .Default; this.mCount = 0; this.mUnique = unique; }
protected void RightRotate(RBTreeNodeBase <T, P> y) { RBTreeNodeBase <T, P> mLeft = y.mLeft; y.mLeft = mLeft.mRight; if (mLeft.mRight != null) { mLeft.mRight.mParent = y; } mLeft.mParent = y.mParent; if (y.mParent == null) { this.mRoot = mLeft; } else if (y == y.mParent.mLeft) { y.mParent.mLeft = mLeft; } else { y.mParent.mRight = mLeft; } mLeft.mRight = y; y.mParent = mLeft; y.OnUpdateCount(); }
protected void LeftRotate(RBTreeNodeBase <T, P> x) { RBTreeNodeBase <T, P> mRight = x.mRight; x.mRight = mRight.mLeft; if (mRight.mLeft != null) { mRight.mLeft.mParent = x; } mRight.mParent = x.mParent; if (x.mParent == null) { this.mRoot = mRight; } else if (x == x.mParent.mLeft) { x.mParent.mLeft = mRight; } else { x.mParent.mRight = mRight; } mRight.mLeft = x; x.mParent = mRight; x.OnUpdateCount(); }
///<summary> ///Return a pointer to the largest key smaller than x ///</summary> protected RBTreeNodeBase <T, P> Predecessor(RBTreeNodeBase <T, P> x) { RBTreeNodeBase <T, P> y; if (x.mLeft != null) { // If left is not NULL then go left one and // then keep going right until we find a node with // no right pointer. for (y = x.mLeft; y.mRight != null; y = y.mRight) { ; } } else { // Go up the tree until we get to a node that is on the // right of its parent (or the root) and then return the // parent. y = x.mParent; while (y != null && x == y.mLeft) { x = y; y = y.mParent; } } return(y); }
protected virtual void Delete(RBTreeNodeBase <T, P> z) { RBTreeNodeBase <T, P> rbTreeNodeBase = z.mLeft == null || z.mRight == null ? z : this.Successor(z); RBTreeNodeBase <T, P> x = rbTreeNodeBase.mLeft == null ? rbTreeNodeBase.mRight : rbTreeNodeBase.mLeft; x?.SetParent(rbTreeNodeBase.mParent); if (rbTreeNodeBase.mParent == null) { this.mRoot = x; } else if (rbTreeNodeBase == rbTreeNodeBase.mParent.mLeft) { rbTreeNodeBase.mParent.SetLeft(x); } else { rbTreeNodeBase.mParent.SetRight(x); } if (rbTreeNodeBase != z) { rbTreeNodeBase.CopyFrom(z); if (z == this.mRoot) { this.mRoot = rbTreeNodeBase; } } if (rbTreeNodeBase.mColor != RBTreeColor.Black || x == null) { return; } this.DeleteFix(x); }
///<summary> ///Copy from other node ///</summary> internal virtual void CopyFrom(RBTreeNodeBase <T, P> z) { if (z.mLeft != null) { z.mLeft.mParent = this; } this.mLeft = z.mLeft; if (z.mRight != null) { z.mRight.mParent = this; } this.mRight = z.mRight; //2) replace z with this in the parent node if (z.mParent != null) { if (z.mParent.mLeft == z) { z.mParent.SetLeft(this); } else { z.mParent.SetRight(this); } } this.mColor = z.mColor; this.SetParent(z.mParent); }
///<summary> ///Tree constructor with comparer ///</summary> public RBTreeBase(IComparer <T> aComparer, bool unique) { mRoot = null; mComparer = aComparer; mCount = 0; mUnique = unique; }
///<summary> ///Tree constructor ///</summary> public RBTreeBase(bool unique) { mRoot = null; mComparer = Comparer <T> .Default; mCount = 0; mUnique = unique; }
///<summary> ///Set parent node ///</summary> internal override void SetParent(RBTreeNodeBase <T, RBOrderedNodeParam> value) { mParent = value; if (mParent != null) { mParent.OnUpdateCount(); } }
public N Last() { RBTreeNodeBase <T, P> rbTreeNodeBase1 = (RBTreeNodeBase <T, P>)null; for (RBTreeNodeBase <T, P> rbTreeNodeBase2 = this.mRoot; rbTreeNodeBase2 != null; rbTreeNodeBase2 = rbTreeNodeBase2.mRight) { rbTreeNodeBase1 = rbTreeNodeBase2; } return(rbTreeNodeBase1 as N); }
public bool Remove(T aKey) { RBTreeNodeBase <T, P> z = (RBTreeNodeBase <T, P>) this.Find(aKey); if (z == null) { return(false); } --this.mCount; this.Delete(z); return(true); }
public N Add(T aKey) { bool aInsert = true; RBTreeNodeBase <T, P> rbTreeNodeBase = this.Traverse(ref aInsert, aKey); if (!aInsert) { throw new ArgumentException(); } ++this.mCount; return(rbTreeNodeBase as N); }
protected void Balance(RBTreeNodeBase <T, P> z) { RBTreeNodeBase <T, P> rbTreeNodeBase = z; while (rbTreeNodeBase != this.mRoot && rbTreeNodeBase.mParent.mColor == RBTreeColor.Red) { if (rbTreeNodeBase.mParent == rbTreeNodeBase.mParent.mParent.mLeft) { RBTreeNodeBase <T, P> mRight = rbTreeNodeBase.mParent.mParent.mRight; if (mRight != null && mRight.mColor == RBTreeColor.Red) { rbTreeNodeBase.mParent.mColor = RBTreeColor.Black; mRight.mColor = RBTreeColor.Black; rbTreeNodeBase.mParent.mParent.mColor = RBTreeColor.Red; rbTreeNodeBase = rbTreeNodeBase.mParent.mParent; } else { if (rbTreeNodeBase == rbTreeNodeBase.mParent.mRight) { rbTreeNodeBase = rbTreeNodeBase.mParent; this.LeftRotate(rbTreeNodeBase); } rbTreeNodeBase.mParent.mColor = RBTreeColor.Black; rbTreeNodeBase.mParent.mParent.mColor = RBTreeColor.Red; this.RightRotate(rbTreeNodeBase.mParent.mParent); } } else { RBTreeNodeBase <T, P> mLeft = rbTreeNodeBase.mParent.mParent.mLeft; if (mLeft != null && mLeft.mColor == RBTreeColor.Red) { rbTreeNodeBase.mParent.mColor = RBTreeColor.Black; mLeft.mColor = RBTreeColor.Black; rbTreeNodeBase.mParent.mParent.mColor = RBTreeColor.Red; rbTreeNodeBase = rbTreeNodeBase.mParent.mParent; } else { if (rbTreeNodeBase == rbTreeNodeBase.mParent.mLeft) { rbTreeNodeBase = rbTreeNodeBase.mParent; this.RightRotate(rbTreeNodeBase); } rbTreeNodeBase.mParent.mColor = RBTreeColor.Black; rbTreeNodeBase.mParent.mParent.mColor = RBTreeColor.Red; this.LeftRotate(rbTreeNodeBase.mParent.mParent); } } } this.mRoot.mColor = RBTreeColor.Black; }
public N Find(T aKey) { RBTreeNodeBase <T, P> x1 = this.mRoot; while (x1 != null) { int num = this.mComparer.Compare(aKey, x1.mKey); if (num < 0) { x1 = x1.mLeft; } else if (num > 0) { x1 = x1.mRight; } else { if (!this.mUnique) { if (object.Equals((object)aKey, (object)x1.mKey)) { return(x1 as N); } RBTreeNodeBase <T, P> x2 = x1; RBTreeNodeBase <T, P> x3 = this.Predecessor(x1); while (x3 != null && this.mComparer.Compare(aKey, x3.mKey) == 0) { x1 = x3; x3 = this.Predecessor(x3); if (object.Equals((object)aKey, (object)x1.mKey)) { return(x1 as N); } } RBTreeNodeBase <T, P> x4 = this.Successor(x2); while (x4 != null && this.mComparer.Compare(aKey, x4.mKey) == 0) { x1 = x4; x4 = this.Successor(x4); if (object.Equals((object)aKey, (object)x1.mKey)) { return(x1 as N); } } } return(x1 as N); } } return(default(N)); }
public int GetOrder(RBOrderedTreeNode <T> aItem) { RBTreeNodeBase <T, RBOrderedNodeParam> rbTreeNodeBase = (RBTreeNodeBase <T, RBOrderedNodeParam>)aItem; int mRank = rbTreeNodeBase.mParam.mRank; for (; rbTreeNodeBase.mParent != null; rbTreeNodeBase = rbTreeNodeBase.mParent) { if (rbTreeNodeBase.mParent.mRight == rbTreeNodeBase) { mRank += rbTreeNodeBase.mParent.mParam.mRank; } } return(mRank - 1); }
///<summary> /// Rotate our tree Left /// /// X rb_left_rotate(X)---> Y /// / \ / \ /// A Y X C /// / \ / \ /// B C A B /// /// N.B. This does not change the ordering. /// /// We assume that neither X or Y is NULL /// </summary> protected void LeftRotate(RBTreeNodeBase <T, P> x) { RBTreeNodeBase <T, P> y; // set Y y = x.mRight; // Turn Y's left subtree into X's right subtree (move B) x.mRight = y.mLeft; // If B is not null, set it's parent to be X if (y.mLeft != null) { y.mLeft.mParent = x; } // Set Y's parent to be what X's parent was y.mParent = x.mParent; // if X was the root if (x.mParent == null) { mRoot = y; } else { // Set X's parent's left or right pointer to be Y if (x == x.mParent.mLeft) { x.mParent.mLeft = y; } else { x.mParent.mRight = y; } } // Put X on Y's left y.mLeft = x; // Set X's parent to be Y x.mParent = y; x.OnUpdateCount(); }
///<summary> /// Rotate our tree Right /// /// X Y /// / \ / \ /// A Y leftArrow--rb_right_rotate(Y) X C /// / \ / \ /// B C A B /// /// N.B. This does not change the ordering. /// /// We assume that neither X or Y is NULL ///</summary>> protected void RightRotate(RBTreeNodeBase <T, P> y) { RBTreeNodeBase <T, P> x; // set X x = y.mLeft; // Turn X's right subtree into Y's left subtree (move B) y.mLeft = x.mRight; // If B is not null, set it's parent to be Y if (x.mRight != null) { x.mRight.mParent = y; } // Set X's parent to be what Y's parent was x.mParent = y.mParent; // if Y was the root if (y.mParent == null) { mRoot = x; } else { // Set Y's parent's left or right pointer to be X if (y == y.mParent.mLeft) { y.mParent.mLeft = x; } else { y.mParent.mRight = x; } } // Put Y on X's right x.mRight = y; // Set Y's parent to be X y.mParent = x; y.OnUpdateCount(); }
///<summary> ///Get order index of item ///This operation is O(logN) operation ///</summary> public int GetOrder(RBOrderedTreeNode <T> aItem) { RBTreeNodeBase <T, RBOrderedNodeParam> node = aItem; int idx = node.mParam.mRank; while (true) { if (node.mParent == null) { break; } if (node.mParent.mRight == node) { idx += node.mParent.mParam.mRank; } node = node.mParent; } return(idx - 1); }
protected RBTreeNodeBase <T, P> Predecessor(RBTreeNodeBase <T, P> x) { RBTreeNodeBase <T, P> rbTreeNodeBase; if (x.mLeft != null) { rbTreeNodeBase = x.mLeft; while (rbTreeNodeBase.mRight != null) { rbTreeNodeBase = rbTreeNodeBase.mRight; } } else { for (rbTreeNodeBase = x.mParent; rbTreeNodeBase != null && x == rbTreeNodeBase.mLeft; rbTreeNodeBase = rbTreeNodeBase.mParent) { x = rbTreeNodeBase; } } return(rbTreeNodeBase); }
public RBOrderedTreeNode <T> GetByOrder(int idx) { int num = idx + 1; RBTreeNodeBase <T, RBOrderedNodeParam> rbTreeNodeBase = this.mRoot; while (rbTreeNodeBase != null && num > 0) { if (num < rbTreeNodeBase.mParam.mRank) { rbTreeNodeBase = rbTreeNodeBase.mLeft; } else if (num > rbTreeNodeBase.mParam.mRank) { num -= rbTreeNodeBase.mParam.mRank; rbTreeNodeBase = rbTreeNodeBase.mRight; } else if (num == rbTreeNodeBase.mParam.mRank) { return(rbTreeNodeBase as RBOrderedTreeNode <T>); } } return((RBOrderedTreeNode <T>)null); }
///<summary> ///Get item by order index ///This operation is O(logN) operation ///</summary> public RBOrderedTreeNode <T> GetByOrder(int idx) { int m = idx + 1; RBTreeNodeBase <T, RBOrderedNodeParam> node = mRoot; while (node != null && m > 0) { if (m < node.mParam.mRank) { node = node.mLeft; } else if (m > node.mParam.mRank) { m = m - node.mParam.mRank; node = node.mRight; } else if (m == node.mParam.mRank) { return(node as RBOrderedTreeNode <T>); } } return(null); }
///<summary> ///Set right node ///</summary> internal virtual void SetRight(RBTreeNodeBase <T, P> value) { mRight = value; }
///<summary> ///Set left node ///</summary> internal virtual void SetLeft(RBTreeNodeBase <T, P> value) { mLeft = value; }
///<summary> ///Set parent node ///</summary> internal virtual void SetParent(RBTreeNodeBase <T, P> value) { mParent = value; }
protected void DeleteFix(RBTreeNodeBase <T, P> x) { while (x != this.mRoot && x.mColor == RBTreeColor.Black) { if (x == x.mParent.mLeft) { RBTreeNodeBase <T, P> mRight = x.mParent.mRight; if (mRight == null) { x = x.mParent; } else { if (mRight.mColor == RBTreeColor.Red) { mRight.mColor = RBTreeColor.Black; x.mParent.mColor = RBTreeColor.Red; this.LeftRotate(x.mParent); mRight = x.mParent.mRight; } if (mRight == null) { x = x.mParent; } else if ((mRight.mLeft == null || mRight.mLeft.mColor == RBTreeColor.Black) && (mRight.mRight == null || mRight.mRight.mColor == RBTreeColor.Black)) { mRight.mColor = RBTreeColor.Red; x = x.mParent; } else { if (mRight.mRight == null || mRight.mRight.mColor == RBTreeColor.Black) { if (mRight.mLeft != null) { mRight.mLeft.mColor = RBTreeColor.Black; } mRight.mColor = RBTreeColor.Red; this.RightRotate(mRight); mRight = x.mParent.mRight; } mRight.mColor = x.mParent.mColor; x.mParent.mColor = RBTreeColor.Black; if (mRight.mRight != null) { mRight.mRight.mColor = RBTreeColor.Black; } this.LeftRotate(x.mParent); x = this.mRoot; } } } else { RBTreeNodeBase <T, P> mLeft = x.mParent.mLeft; if (mLeft == null) { x = x.mParent; } else { if (mLeft.mColor == RBTreeColor.Red) { mLeft.mColor = RBTreeColor.Black; x.mParent.mColor = RBTreeColor.Red; this.RightRotate(x.mParent); mLeft = x.mParent.mLeft; } if (mLeft == null) { x = x.mParent; } else if ((mLeft.mRight == null || mLeft.mRight.mColor == RBTreeColor.Black) && (mLeft.mLeft == null || mLeft.mLeft.mColor == RBTreeColor.Black)) { mLeft.mColor = RBTreeColor.Red; x = x.mParent; } else { if (mLeft.mLeft == null || mLeft.mLeft.mColor == RBTreeColor.Black) { if (mLeft.mRight != null) { mLeft.mRight.mColor = RBTreeColor.Black; } mLeft.mColor = RBTreeColor.Red; this.LeftRotate(mLeft); mLeft = x.mParent.mLeft; } mLeft.mColor = x.mParent.mColor; x.mParent.mColor = RBTreeColor.Black; if (mLeft.mLeft != null) { mLeft.mLeft.mColor = RBTreeColor.Black; } this.RightRotate(x.mParent); x = this.mRoot; } } } } x.mColor = RBTreeColor.Black; }
///<summary> ///Copy from other node ///</summary> internal override void CopyFrom(RBTreeNodeBase <T, RBOrderedNodeParam> z) { this.mParam.mRank = z.mParam.mRank; this.mParam.mCount = z.mParam.mCount; base.CopyFrom(z); }
///<summary> ///Set right node ///</summary> internal override void SetRight(RBTreeNodeBase <T, RBOrderedNodeParam> value) { mRight = value; OnUpdateCount(); }
public void Clear() { this.mRoot = (RBTreeNodeBase <T, P>)null; this.mCount = 0; }