public k_Node mk_Left, mk_Right, mk_Parent; // public to simplify fixup & clone (passing by ref) public k_Node(object ak_Key, object ak_Value, k_Node ak_Parent) { mk_Key = ak_Key; mk_Value = ak_Value; mk_Parent = ak_Parent; mb_Red = true; }
public void Clear() { mi_Count = 0; mk_Head = null; mk_Left = null; mk_Right = null; }
private k_Node CloneR(k_Node ak_Node, k_Node ak_NextHigher) { k_Node lk_New = new k_Node(ak_Node.Key, ak_Node.Value, ak_Node.Height); for (int i = ak_Node.Height - 1; i >= 0; --i) { // simply copy two links with equal target next to each other if (i < ak_Node.Height - 1 && object.ReferenceEquals(ak_Node.Next[i], ak_Node.Next[i + 1])) { lk_New.Next[i] = lk_New.Next[i + 1]; continue; } k_Node lk_Next = ak_Node.Next[i]; if (lk_Next != null && lk_Next.Height - 1 <= i) { k_Node lk_Higher = (i < ak_Node.Height - 1) ? ak_Node.Next[i + 1] : ak_NextHigher; lk_New.Next[i] = CloneR(lk_Next, lk_Higher); } else { lk_New.Next[i] = ak_NextHigher; } } return(lk_New); }
private void PasteNodeRange(k_NodeIterator ak_Where, k_Node ak_First, k_Node ak_Last) { if (ak_Where != this.End) { k_Node lk_Next = ak_Where.Node; k_Node lk_Prev = lk_Next.mk_Prev; ak_Last.mk_Next = lk_Next; ak_First.mk_Prev = lk_Prev; if (lk_Next != null) { lk_Next.mk_Prev = ak_Last; } if (lk_Prev != null) { lk_Prev.mk_Next = ak_First; } } else { if (mk_Tail != null) { mk_Tail.mk_Next = ak_First; ak_First.mk_Prev = mk_Tail; } mk_Tail = ak_Last; } if (ak_Where == this.Begin) { mk_Head = ak_First; mk_Begin = null; // recalc on next get } }
private int ComparePos(k_Node ak_Left, k_Node ak_Right) { if (object.ReferenceEquals(ak_Left, ak_Right)) { return(0); } int li_Diff = mk_Comparer.Compare(ak_Left.Key, ak_Right.Key); if (li_Diff != 0) { return(li_Diff); } k_Node lk_Current = ak_Left; for (;;) { if (lk_Current == null || mk_Comparer.Compare(lk_Current.Key, ak_Right.Key) > 0) { return(1); } else if (object.ReferenceEquals(lk_Current, ak_Right)) { return(-1); } lk_Current = lk_Current.Next[0]; } }
/* * A left rotation: ak_Node.Right takes old position of ak_Node. * Makes the old root the left subtree of the new root. * * 5 7 * 2 7 -> 5 8 * 1 3 6 8 2 6 * 1 3 */ private k_Node RotateLeft(k_Node ak_Node) { k_Node lk_Tmp = ak_Node.mk_Right; lk_Tmp.mk_Parent = ak_Node.mk_Parent; ak_Node.mk_Parent = lk_Tmp; ak_Node.mk_Right = lk_Tmp.mk_Left; if (ak_Node.mk_Right != null) { ak_Node.mk_Right.mk_Parent = ak_Node; } lk_Tmp.mk_Left = ak_Node; // correct parent if (lk_Tmp.mk_Parent == null) { mk_Head = lk_Tmp; } else if (lk_Tmp.mk_Parent.mk_Right == ak_Node) { lk_Tmp.mk_Parent.mk_Right = lk_Tmp; } else { lk_Tmp.mk_Parent.mk_Left = lk_Tmp; } return(lk_Tmp); }
private void Insert(ref k_Node ak_Node, k_Node ak_Parent, object ak_Key, object ak_Value, bool ab_RightMove) { if (ak_Node == null) { ak_Node = new k_Node(ak_Key, ak_Value, ak_Parent); if (object.ReferenceEquals(ak_Parent, mk_Right) && (ak_Parent == null || ab_RightMove)) { mk_Right = ak_Node; } if (object.ReferenceEquals(ak_Parent, mk_Left) && (ak_Parent == null || !ab_RightMove)) { mk_Left = ak_Node; } return; } if (IsRed(ak_Node.mk_Left) && IsRed(ak_Node.mk_Right)) { ak_Node.Red = true; ak_Node.mk_Left.Red = false; ak_Node.mk_Right.Red = false; } int li_Diff = mk_Comparer.Compare(ak_Key, ak_Node.Key); if (!mb_AllowDuplicateKeys && li_Diff == 0) { throw new ArgumentException("An element with the same key already exists in the tree."); } if (li_Diff < 0) { Insert(ref ak_Node.mk_Left, ak_Node, ak_Key, ak_Value, false); if (IsRed(ak_Node) && IsRed(ak_Node.mk_Left) && ab_RightMove) { ak_Node = RotateRight(ak_Node); } if (IsRed(ak_Node.mk_Left) && IsRed(ak_Node.mk_Left.mk_Left)) { ak_Node = RotateRight(ak_Node); ak_Node.Red = false; ak_Node.mk_Right.Red = true; } } else { Insert(ref ak_Node.mk_Right, ak_Node, ak_Key, ak_Value, true); if (IsRed(ak_Node) && IsRed(ak_Node.mk_Right) && !ab_RightMove) { ak_Node = RotateLeft(ak_Node); } if (IsRed(ak_Node.mk_Right) && IsRed(ak_Node.mk_Right.mk_Right)) { ak_Node = RotateLeft(ak_Node); ak_Node.Red = false; ak_Node.mk_Left.Red = true; } } }
public void Insert(k_Iterator ak_Where, object ak_Value) { //System.Diagnostics.Debug.Assert(object.ReferenceEquals(this, ak_Where.Collection), "Iterator does not belong to this collection."); k_Node lk_New = new k_Node(ak_Value); PasteNodeRange((k_NodeIterator)ak_Where, lk_New, lk_New); ++mi_Count; }
public k_SkipList(IComparer ak_Comparer, double ad_Prob, int ai_MaxLevel) { if (ad_Prob >= 1.0 || ad_Prob <= 0) throw new ArgumentException("Invalid probability. Must be (0-1).", "ad_Prob"); md_Prob = ad_Prob; mi_MaxLevel = ai_MaxLevel; mk_Comparer = ak_Comparer; mk_Head = new k_Node(null, null, ai_MaxLevel); mk_End = new k_PinnedNodeIterator(this, null); }
public static void SwapItems(k_Node ak_A, k_Node ak_B) { object lk_Tmp = ak_A.mk_Key; ak_A.mk_Key = ak_B.mk_Key; ak_B.mk_Key = lk_Tmp; lk_Tmp = ak_A.mk_Value; ak_A.mk_Value = ak_B.mk_Value; ak_B.mk_Value = lk_Tmp; }
public k_Iterator Find(object ak_Value) { DictionaryEntry lr_Item = (DictionaryEntry)ak_Value; k_Node lk_Found = FindInternal(mk_Head, lr_Item.Key); if (lk_Found != null && mk_Comparer.Compare(lk_Found.Value, lr_Item.Value) == 0) { return(new k_NodeIterator(this, lk_Found)); } return(this.End); }
public k_SkipList(IComparer ak_Comparer, double ad_Prob, int ai_MaxLevel) { if (ad_Prob >= 1.0 || ad_Prob <= 0) { throw new ArgumentException("Invalid probability. Must be (0-1).", "ad_Prob"); } md_Prob = ad_Prob; mi_MaxLevel = ai_MaxLevel; mk_Comparer = ak_Comparer; mk_Head = new k_Node(null, null, ai_MaxLevel); mk_End = new k_PinnedNodeIterator(this, null); }
/// <summary> /// Return leftmost node in subtree. /// </summary> /// <param name="ak_Node">Node where to start search</param> /// <returns>Found node</returns> private static k_Node LeftMost(k_Node ak_Node) { if (ak_Node == null) { return(null); } while (ak_Node.mk_Left != null) { ak_Node = ak_Node.mk_Left; } return(ak_Node); }
/// <summary> /// Return rightmost node in subtree. /// </summary> /// <param name="ak_Node">Node where to start search</param> /// <returns>Found node</returns> private static k_Node RightMost(k_Node ak_Node) { if (ak_Node == null) { return(null); } while (ak_Node.mk_Right != null) { ak_Node = ak_Node.mk_Right; } return(ak_Node); }
public k_Iterator Erase(k_Iterator ak_First, k_Iterator ak_Last) { //System.Diagnostics.Debug.Assert(object.ReferenceEquals(this, ak_First.Collection) && object.ReferenceEquals(this, ak_Last.Collection), "Iterators do not belong to this collection."); int li_Distance = ak_Last - ak_First; if (li_Distance == 0) { return(ak_Last); } k_Node lk_First = ((k_NodeIterator)ak_First).Node; k_Node lk_Prev = lk_First.mk_Prev; k_Node lk_Next = (ak_Last != this.End) ? ((k_NodeIterator)ak_Last).Node : null; if (lk_Prev != null) { lk_Prev.mk_Next = lk_Next; } else { //System.Diagnostics.Debug.Assert(object.ReferenceEquals(mk_Head, lk_First), "Inconsistent list state"); mk_Head = lk_Next; mk_Begin = null; } if (lk_Next != null) { lk_Next.mk_Prev = lk_Prev; } else { //System.Diagnostics.Debug.Assert(object.ReferenceEquals(mk_Tail, ((k_NodeIterator)(ak_Last-1)).Node), "Inconsistent list state"); mk_Tail = lk_Prev; } mi_Count -= li_Distance; #if (DEBUG) // create invalid nodes linking to itself k_Node lk_Node = lk_First; while (lk_Node != null && lk_Node != lk_Next) { k_Node lk_Tmp = lk_Node.mk_Next; lk_Node.mk_Next = lk_Node; lk_Node.mk_Prev = lk_Node; lk_Node = lk_Tmp; } #endif return(ak_Last); }
private k_Node FindInternal(k_Node ak_Node, object ak_Key) { while (ak_Node != null) { int li_Diff = mk_Comparer.Compare(ak_Key, ak_Node.Key); if (li_Diff == 0) { return(ak_Node); } ak_Node = (li_Diff < 0) ? ak_Node.mk_Left : ak_Node.mk_Right; } return(null); }
private void CloneRecursive(k_Node ak_Node, k_Node ak_Parent, ref k_Node ak_Link) { if (ak_Node == null) { return; } ak_Link = new k_Node(ak_Node.Key, ak_Node.Value, ak_Parent); ak_Link.Red = ak_Node.Red; CloneRecursive(ak_Node.mk_Left, ak_Link, ref ak_Link.mk_Left); CloneRecursive(ak_Node.mk_Right, ak_Link, ref ak_Link.mk_Right); }
/// <summary> /// Return rightmost node in list. /// </summary> /// <returns>Found node</returns> private k_Node RightMost() { k_Node lk_Current = mk_Head.Next[mi_HighestNode - 1]; for (int li_Level = mi_HighestNode - 1; li_Level >= 0; --li_Level) { while (lk_Current.Next[li_Level] != null) { lk_Current = lk_Current.Next[li_Level]; } } return(lk_Current); }
private static k_Node Previous(k_Node ak_Node) // the next smaller { if (ak_Node.mk_Left != null) { return(RightMost(ak_Node.mk_Left)); } k_Node lk_Parent = ak_Node.mk_Parent; while (lk_Parent != null && lk_Parent.mk_Left == ak_Node) { ak_Node = lk_Parent; lk_Parent = lk_Parent.mk_Parent; } return(lk_Parent); }
private static k_Node Next(k_Node ak_Node) { if (ak_Node.mk_Right != null) { return(LeftMost(ak_Node.mk_Right)); } k_Node lk_Parent = ak_Node.mk_Parent; while (lk_Parent != null && lk_Parent.mk_Right == ak_Node) { ak_Node = lk_Parent; lk_Parent = lk_Parent.mk_Parent; } return(lk_Parent); }
public override void Move(int ai_Count) { k_Node lk_NewPos = mk_Current; int li_Count = ai_Count; if (li_Count > 0) { while (li_Count-- > 0) { if (lk_NewPos == null) { throw new InvalidOperationException("Tried to moved beyond end element."); } lk_NewPos = lk_NewPos.mk_Next; } } else { while (li_Count++ < 0) { if (lk_NewPos == null) { lk_NewPos = mk_List.mk_Tail; } else { lk_NewPos = lk_NewPos.mk_Prev; } if (lk_NewPos == null) { throw new InvalidOperationException("Tried to move before first element."); } } } #if (DEBUG) if (ai_Count != 0 && object.ReferenceEquals(mk_Current, lk_NewPos)) { throw new IndexOutOfRangeException("Iterator is positioned on invalid node."); } #endif mk_Current = lk_NewPos; }
private void FindInsertPos(k_Node ak_Node) { k_Node lk_Current = mk_Head; for (int li_Level = mi_HighestNode - 1; li_Level >= 0; --li_Level) { while (lk_Current.Next[li_Level] != null && mk_Comparer.Compare(lk_Current.Next[li_Level].Key, ak_Node.Key) < 0) { lk_Current = lk_Current.Next[li_Level]; } if (li_Level < ak_Node.Height) { ak_Node.Next[li_Level] = lk_Current; } } }
private k_Node Previous(k_Node ak_Node) { k_Node lk_Current = mk_Head; for (int li_Level = mi_HighestNode - 1; li_Level >= 0; --li_Level) { while (lk_Current.Next[li_Level] != null) { int li_Diff = mk_Comparer.Compare(lk_Current.Next[li_Level].Key, ak_Node.Key); if (li_Diff > 0) { break; } if (li_Diff == 0) { k_Node lk_Next = lk_Current; while (lk_Next != null && !object.ReferenceEquals(lk_Next.Next[0], ak_Node)) { if (mk_Comparer.Compare(lk_Next.Key, ak_Node.Key) > 0) { lk_Next = null; } else { lk_Next = lk_Next.Next[0]; } } if (lk_Next == null) { break; } return(lk_Next); // found previous node during right-scan of nodes with equal key value } lk_Current = lk_Current.Next[li_Level]; } } if (object.ReferenceEquals(mk_Head, lk_Current)) { return(null); } return(lk_Current); }
public k_Iterator UpperBound(object ak_Key) { k_Node lk_Node = mk_Head; k_Node lk_Found = null; while (lk_Node != null) { if (mk_Comparer.Compare(lk_Node.Key, ak_Key) > 0) { lk_Found = lk_Node; lk_Node = lk_Node.mk_Left; } else { lk_Node = lk_Node.mk_Right; } } return(new k_NodeIterator(this, lk_Found)); }
private void RemoveNode(k_Node ak_Node) { if (ak_Node == null) { return; } if (ak_Node == mk_Head) { UnlinkNode(ref mk_Head); } else if (ak_Node == ak_Node.mk_Parent.mk_Right) { UnlinkNode(ref ak_Node.mk_Parent.mk_Right); } else { UnlinkNode(ref ak_Node.mk_Parent.mk_Left); } }
public void Insert(k_Iterator ak_Where, object ak_Value, int ai_Count) { //System.Diagnostics.Debug.Assert(object.ReferenceEquals(this, ak_Where.Collection), "Iterator does not belong to this collection."); k_Node lk_Start = new k_Node(null), lk_End = lk_Start; for (int i = 0; i < ai_Count; ++i) { k_Node lk_New = new k_Node(ak_Value); lk_End.mk_Next = lk_New; lk_New.mk_Prev = lk_End; lk_End = lk_New; } if (ai_Count > 0) { PasteNodeRange((k_NodeIterator)ak_Where, lk_Start.mk_Next, lk_End); mi_Count += ai_Count; } }
public void Add(object ak_Key, object ak_Value) { k_Node lk_Node = new k_Node(ak_Key, ak_Value, CalcNewNodeHeight()); if (lk_Node.Height > mi_HighestNode) { mi_HighestNode = lk_Node.Height; } FindInsertPos(lk_Node); for (int i = 0; i < lk_Node.Height; ++i) { k_Node lk_Left = lk_Node.Next[i]; k_Node lk_Tmp = lk_Left.Next[i]; lk_Left.Next[i] = lk_Node; lk_Node.Next[i] = lk_Tmp; } ++mi_Count; }
public void Insert(k_Iterator ak_Where, k_Iterator ak_SrcBegin, k_Iterator ak_SrcEnd) { //System.Diagnostics.Debug.Assert(object.ReferenceEquals(this, ak_Where.Collection), "Iterator does not belong to this collection."); k_Node lk_Start = new k_Node(null), lk_End = lk_Start; int li_Count = 0; for (k_Iterator lk_Iter = ak_SrcBegin.Clone(); lk_Iter != ak_SrcEnd; lk_Iter.Next(), ++li_Count) { k_Node lk_New = new k_Node(lk_Iter.Current); lk_End.mk_Next = lk_New; lk_New.mk_Prev = lk_End; lk_End = lk_New; } if (li_Count > 0) { PasteNodeRange((k_NodeIterator)ak_Where, lk_Start.mk_Next, lk_End); mi_Count += li_Count; } }
public override void Move(int ai_Count) { k_Node lk_NewPos = mk_Current; if (ai_Count > 0) { while (ai_Count-- > 0) { if (lk_NewPos == null) { throw new InvalidOperationException("Tried to moved beyond end element."); } lk_NewPos = k_Tree.Next(lk_NewPos); } } else { while (ai_Count++ < 0) { if (lk_NewPos == null) { lk_NewPos = mk_Tree.mk_Right; } else { lk_NewPos = k_Tree.Previous(lk_NewPos); } if (lk_NewPos == null) { throw new InvalidOperationException("Tried to move before first element."); } } } mk_Current = lk_NewPos; }
/// <summary> /// Returns an iterator to the first element in a list with a key value /// that is greater than that of a specified key. /// </summary> /// <param name="ak_Key"> /// The argument key value to be compared with the sort key of an element /// from the list being searched. /// </param> /// <returns> /// Location of an element in a list that with a key that is greater /// than the argument key, or this.End if no match is found for the key. /// </returns> public k_Iterator UpperBound(object ak_Key) { k_Node lk_Found = null; k_Node lk_Current = mk_Head; for (int li_Level = mi_HighestNode - 1; li_Level >= 0; --li_Level) { k_Node lk_Next = lk_Current.Next[li_Level]; while (lk_Next != null) { int li_Diff = mk_Comparer.Compare(lk_Next.Key, ak_Key); if (li_Diff > 0) { lk_Found = lk_Next; break; } lk_Current = lk_Next; lk_Next = lk_Next.Next[li_Level]; } } return(new k_NodeIterator(this, lk_Found)); }
public object this[object ak_Key] { get { k_Node lk_Node = FindInternal(mk_Head, ak_Key); if (lk_Node == null) { return(null); } return(lk_Node.Value); } set { k_Node lk_Node = FindInternal(mk_Head, ak_Key); if (lk_Node == null) { Add(new DictionaryEntry(ak_Key, value)); } else { lk_Node.Value = value; } } }
public k_PinnedNodeIterator(k_Tree ak_Tree, k_Node ak_Node) : base(ak_Tree, ak_Node) { }
public void Clear() { mk_Head = mk_Tail = null; mk_Begin = mk_End; mi_Count = 0; }
/// <summary> /// Return rightmost node in subtree. /// </summary> /// <param name="ak_Node">Node where to start search</param> /// <returns>Found node</returns> private static k_Node RightMost(k_Node ak_Node) { if (ak_Node == null) return null; while (ak_Node.mk_Right != null) ak_Node = ak_Node.mk_Right; return ak_Node; }
public override void Move(int ai_Count) { k_Node lk_NewPos = mk_Current; if (ai_Count > 0) { while (ai_Count-- > 0) { if (lk_NewPos == null) throw new InvalidOperationException("Tried to moved beyond end element."); lk_NewPos = k_Tree.Next(lk_NewPos); } } else { while (ai_Count++ < 0) { if (lk_NewPos == null) lk_NewPos = mk_Tree.mk_Right; else lk_NewPos = k_Tree.Previous(lk_NewPos); if (lk_NewPos == null) throw new InvalidOperationException("Tried to move before first element."); } } mk_Current = lk_NewPos; }
private void PasteNodeRange(k_NodeIterator ak_Where, k_Node ak_First, k_Node ak_Last) { if (ak_Where != this.End) { k_Node lk_Next = ak_Where.Node; k_Node lk_Prev = lk_Next.mk_Prev; ak_Last.mk_Next = lk_Next; ak_First.mk_Prev = lk_Prev; if (lk_Next != null) lk_Next.mk_Prev = ak_Last; if (lk_Prev != null) lk_Prev.mk_Next = ak_First; } else { if (mk_Tail != null) { mk_Tail.mk_Next = ak_First; ak_First.mk_Prev = mk_Tail; } mk_Tail = ak_Last; } if (ak_Where == this.Begin) { mk_Head = ak_First; mk_Begin = null; // recalc on next get } }
public override void Move(int ai_Count) { k_Node lk_NewPos = mk_Current; int li_Count = ai_Count; if (li_Count > 0) { while (li_Count-- > 0) { if (lk_NewPos == null) throw new InvalidOperationException("Tried to moved beyond end element."); lk_NewPos = lk_NewPos.mk_Next; } } else { while (li_Count++ < 0) { if (lk_NewPos == null) lk_NewPos = mk_List.mk_Tail; else lk_NewPos = lk_NewPos.mk_Prev; if (lk_NewPos == null) throw new InvalidOperationException("Tried to move before first element."); } } #if (DEBUG) if (ai_Count != 0 && object.ReferenceEquals(mk_Current, lk_NewPos)) throw new IndexOutOfRangeException("Iterator is positioned on invalid node."); #endif mk_Current = lk_NewPos; }
/* A right rotation: ak_Node.Left takes old position of ak_Node. Makes the old root the right subtree of the new root. 5 2 2 7 -> 1 5 1 3 6 8 3 7 6 8 */ private k_Node RotateRight(k_Node ak_Node) { k_Node lk_Tmp = ak_Node.mk_Left; lk_Tmp.mk_Parent = ak_Node.mk_Parent; ak_Node.mk_Parent = lk_Tmp; ak_Node.mk_Left = lk_Tmp.mk_Right; if (ak_Node.mk_Left != null) ak_Node.mk_Left.mk_Parent = ak_Node; lk_Tmp.mk_Right = ak_Node; // correct parent if (lk_Tmp.mk_Parent == null) mk_Head = lk_Tmp; else if (lk_Tmp.mk_Parent.mk_Right == ak_Node) lk_Tmp.mk_Parent.mk_Right = lk_Tmp; else lk_Tmp.mk_Parent.mk_Left = lk_Tmp; return lk_Tmp; }
private bool IsRed(k_Node ak_Node) { return (ak_Node != null && ak_Node.Red); }
private void RemoveNode(k_Node ak_Node) { if (ak_Node == null) return; if (ak_Node == mk_Head) UnlinkNode(ref mk_Head); else if (ak_Node == ak_Node.mk_Parent.mk_Right) UnlinkNode(ref ak_Node.mk_Parent.mk_Right); else UnlinkNode(ref ak_Node.mk_Parent.mk_Left); }
private void Insert(ref k_Node ak_Node, k_Node ak_Parent, object ak_Key, object ak_Value, bool ab_RightMove) { if (ak_Node == null) { ak_Node = new k_Node(ak_Key, ak_Value, ak_Parent); if (object.ReferenceEquals(ak_Parent, mk_Right) && (ak_Parent == null || ab_RightMove)) mk_Right = ak_Node; if (object.ReferenceEquals(ak_Parent, mk_Left) && (ak_Parent == null || !ab_RightMove)) mk_Left = ak_Node; return; } if (IsRed(ak_Node.mk_Left) && IsRed(ak_Node.mk_Right)) { ak_Node.Red = true; ak_Node.mk_Left.Red = false; ak_Node.mk_Right.Red = false; } int li_Diff = mk_Comparer.Compare(ak_Key, ak_Node.Key); if (!mb_AllowDuplicateKeys && li_Diff == 0) throw new ArgumentException("An element with the same key already exists in the tree."); if (li_Diff < 0) { Insert(ref ak_Node.mk_Left, ak_Node, ak_Key, ak_Value, false); if (IsRed(ak_Node) && IsRed(ak_Node.mk_Left) && ab_RightMove) ak_Node = RotateRight(ak_Node); if (IsRed(ak_Node.mk_Left) && IsRed(ak_Node.mk_Left.mk_Left)) { ak_Node = RotateRight(ak_Node); ak_Node.Red = false; ak_Node.mk_Right.Red = true; } } else { Insert(ref ak_Node.mk_Right, ak_Node, ak_Key, ak_Value, true); if (IsRed(ak_Node) && IsRed(ak_Node.mk_Right) && !ab_RightMove) ak_Node = RotateLeft(ak_Node); if (IsRed(ak_Node.mk_Right) && IsRed(ak_Node.mk_Right.mk_Right)) { ak_Node = RotateLeft(ak_Node); ak_Node.Red = false; ak_Node.mk_Left.Red = true; } } }
private k_Node FindInternal(k_Node ak_Node, object ak_Key) { while (ak_Node != null) { int li_Diff = mk_Comparer.Compare(ak_Key, ak_Node.Key); if (li_Diff == 0) return ak_Node; ak_Node = (li_Diff < 0) ? ak_Node.mk_Left : ak_Node.mk_Right; } return null; }
private void CloneRecursive(k_Node ak_Node, k_Node ak_Parent, ref k_Node ak_Link) { if (ak_Node == null) return; ak_Link = new k_Node(ak_Node.Key, ak_Node.Value, ak_Parent); ak_Link.Red = ak_Node.Red; CloneRecursive(ak_Node.mk_Left, ak_Link, ref ak_Link.mk_Left); CloneRecursive(ak_Node.mk_Right, ak_Link, ref ak_Link.mk_Right); }
public k_Iterator Erase(k_Iterator ak_First, k_Iterator ak_Last) { //System.Diagnostics.Debug.Assert(object.ReferenceEquals(this, ak_First.Collection) && object.ReferenceEquals(this, ak_Last.Collection), "Iterators do not belong to this collection."); int li_Distance = ak_Last - ak_First; if (li_Distance == 0) return ak_Last; k_Node lk_First = ((k_NodeIterator)ak_First).Node; k_Node lk_Prev = lk_First.mk_Prev; k_Node lk_Next = (ak_Last != this.End) ? ((k_NodeIterator)ak_Last).Node : null; if (lk_Prev != null) lk_Prev.mk_Next = lk_Next; else { //System.Diagnostics.Debug.Assert(object.ReferenceEquals(mk_Head, lk_First), "Inconsistent list state"); mk_Head = lk_Next; mk_Begin = null; } if (lk_Next != null) lk_Next.mk_Prev = lk_Prev; else { //System.Diagnostics.Debug.Assert(object.ReferenceEquals(mk_Tail, ((k_NodeIterator)(ak_Last-1)).Node), "Inconsistent list state"); mk_Tail = lk_Prev; } mi_Count -= li_Distance; #if (DEBUG) // create invalid nodes linking to itself k_Node lk_Node = lk_First; while (lk_Node != null && lk_Node != lk_Next) { k_Node lk_Tmp = lk_Node.mk_Next; lk_Node.mk_Next = lk_Node; lk_Node.mk_Prev = lk_Node; lk_Node = lk_Tmp; } #endif return ak_Last; }
/// <summary> /// Return leftmost node in subtree. /// </summary> /// <param name="ak_Node">Node where to start search</param> /// <returns>Found node</returns> private static k_Node LeftMost(k_Node ak_Node) { if (ak_Node == null) return null; while (ak_Node.mk_Left != null) ak_Node = ak_Node.mk_Left; return ak_Node; }
private void FindInsertPos(k_Node ak_Node) { k_Node lk_Current = mk_Head; for (int li_Level = mi_HighestNode-1; li_Level >= 0; --li_Level) { while (lk_Current.Next[li_Level] != null && mk_Comparer.Compare(lk_Current.Next[li_Level].Key, ak_Node.Key) < 0) lk_Current = lk_Current.Next[li_Level]; if (li_Level < ak_Node.Height) ak_Node.Next[li_Level] = lk_Current; } }
public void Insert(k_Iterator ak_Where, object ak_Value, int ai_Count) { //System.Diagnostics.Debug.Assert(object.ReferenceEquals(this, ak_Where.Collection), "Iterator does not belong to this collection."); k_Node lk_Start = new k_Node(null), lk_End = lk_Start; for (int i=0; i<ai_Count; ++i) { k_Node lk_New = new k_Node(ak_Value); lk_End.mk_Next = lk_New; lk_New.mk_Prev = lk_End; lk_End = lk_New; } if (ai_Count > 0) { PasteNodeRange((k_NodeIterator)ak_Where, lk_Start.mk_Next, lk_End); mi_Count += ai_Count; } }
public k_NodeIterator(k_List ak_List, k_Node ak_Node) { mk_List = ak_List; mk_Current = ak_Node; }
private k_Node Previous(k_Node ak_Node) { k_Node lk_Current = mk_Head; for (int li_Level = mi_HighestNode-1; li_Level >= 0; --li_Level) { while (lk_Current.Next[li_Level] != null) { int li_Diff = mk_Comparer.Compare(lk_Current.Next[li_Level].Key, ak_Node.Key); if (li_Diff > 0) break; if (li_Diff == 0) { k_Node lk_Next = lk_Current; while (lk_Next != null && !object.ReferenceEquals(lk_Next.Next[0], ak_Node)) { if (mk_Comparer.Compare(lk_Next.Key, ak_Node.Key) > 0) lk_Next = null; else lk_Next = lk_Next.Next[0]; } if (lk_Next == null) break; return lk_Next; // found previous node during right-scan of nodes with equal key value } lk_Current = lk_Current.Next[li_Level]; } } if (object.ReferenceEquals(mk_Head, lk_Current)) return null; return lk_Current; }
public k_PinnedNodeIterator(k_List ak_List, k_Node ak_Node) : base(ak_List, ak_Node) { }
// the next smaller private static k_Node Previous(k_Node ak_Node) { if (ak_Node.mk_Left != null) return RightMost(ak_Node.mk_Left); k_Node lk_Parent = ak_Node.mk_Parent; while (lk_Parent != null && lk_Parent.mk_Left == ak_Node) { ak_Node = lk_Parent; lk_Parent = lk_Parent.mk_Parent; } return lk_Parent; }
public k_NodeIterator(k_Tree ak_Tree, k_Node ak_Node) { mk_Tree = ak_Tree; mk_Current = ak_Node; }
private void UnlinkNode(ref k_Node ak_Node) { bool lb_Red = ak_Node.Red; k_Node lk_Erased = ak_Node; k_Node lk_PatchNode = null; if (ak_Node.mk_Right == null) lk_PatchNode = ak_Node.mk_Left; else if (ak_Node.mk_Left == null) lk_PatchNode = ak_Node.mk_Right; else lk_PatchNode = ak_Node; k_Node lk_PatchParent = null, lk_FixNode = null; if (lk_PatchNode == null) { lk_PatchParent = ak_Node.mk_Parent; ak_Node = null; } else if (lk_PatchNode != ak_Node) { lk_PatchNode.mk_Parent = ak_Node.mk_Parent; ak_Node = lk_PatchNode; lk_PatchParent = lk_PatchNode.mk_Parent; } else { // two subtrees lk_PatchNode = RightMost(ak_Node.mk_Left); if (lk_PatchNode.mk_Parent.mk_Right == lk_PatchNode) lk_PatchNode.mk_Parent.mk_Right = lk_PatchNode.mk_Left; else lk_PatchNode.mk_Parent.mk_Left = lk_PatchNode.mk_Left; lb_Red = lk_PatchNode.Red; if (lk_PatchNode.mk_Left != null) lk_PatchNode.mk_Left.mk_Parent = lk_PatchNode.mk_Parent; lk_PatchParent = lk_PatchNode.mk_Parent; lk_FixNode = lk_PatchNode.mk_Left; k_Node.SwapItems(ak_Node, lk_PatchNode); // ensure that mk_Left and/or mk_Right are corrected after unlink lk_Erased = lk_PatchNode; } if (!lb_Red && lk_PatchParent != null) { // erased node was black link - rebalance the tree while (!IsRed(lk_FixNode) && lk_FixNode != mk_Head) { if (lk_PatchParent.mk_Left != null || lk_PatchParent.mk_Right != null) { if (lk_PatchParent.mk_Left == lk_FixNode) { // fixup right subtree k_Node lk_Node = lk_PatchParent.mk_Right; if (IsRed(lk_Node)) { lk_Node.Red = false; lk_PatchParent.Red = true; RotateLeft(lk_PatchParent); lk_Node = lk_PatchParent.mk_Right; } if (lk_Node != null) { if (!IsRed(lk_Node.mk_Left) && !IsRed(lk_Node.mk_Right)) lk_Node.Red = true; else { if (!IsRed(lk_Node.mk_Right)) { lk_Node.Red = true; lk_Node.mk_Left.Red = false; RotateRight(lk_Node); lk_Node = lk_PatchParent.mk_Right; } lk_Node.Red = lk_PatchParent.Red; lk_PatchParent.Red = false; lk_Node.mk_Right.Red = false; RotateLeft(lk_PatchParent); break; } } } else { // fixup leftsubtree k_Node lk_Node = lk_PatchParent.mk_Left; if (IsRed(lk_Node)) { lk_Node.Red = false; lk_PatchParent.Red = true; RotateRight(lk_PatchParent); lk_Node = lk_PatchParent.mk_Left; } if (lk_Node != null) { if (!IsRed(lk_Node.mk_Left) && !IsRed(lk_Node.mk_Right)) lk_Node.Red = true; else { if (!IsRed(lk_Node.mk_Left)) { lk_Node.Red = true; lk_Node.mk_Right.Red = false; RotateLeft(lk_Node); lk_Node = lk_PatchParent.mk_Left; } lk_Node.Red = lk_PatchParent.Red; lk_PatchParent.Red = false; lk_Node.mk_Left.Red = false; RotateRight(lk_PatchParent); break; } } } } lk_FixNode = lk_PatchParent; lk_PatchParent = lk_PatchParent.mk_Parent; } if (lk_FixNode != null) lk_FixNode.Red = false; } --mi_Count; if (object.ReferenceEquals(lk_Erased, mk_Right)) mk_Right = k_Tree.RightMost(mk_Head); if (object.ReferenceEquals(lk_Erased, mk_Left)) mk_Left = k_Tree.LeftMost(mk_Head); }
private k_Node Next(k_Node ak_Node) { return ak_Node.Next[0]; }
private static k_Node Next(k_Node ak_Node) { if (ak_Node.mk_Right != null) return LeftMost(ak_Node.mk_Right); k_Node lk_Parent = ak_Node.mk_Parent; while (lk_Parent != null && lk_Parent.mk_Right == ak_Node) { ak_Node = lk_Parent; lk_Parent = lk_Parent.mk_Parent; } return lk_Parent; }
public k_Node(object ak_Key, object ak_Value, k_Node ak_Parent) { mk_Key = ak_Key; mk_Value = ak_Value; mk_Parent = ak_Parent; mb_Red = true; }