Пример #1
0
            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;
            }
Пример #2
0
 public void Clear()
 {
     mi_Count = 0;
     mk_Head  = null;
     mk_Left  = null;
     mk_Right = null;
 }
Пример #3
0
        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);
        }
Пример #4
0
        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
            }
        }
Пример #5
0
        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];
            }
        }
Пример #6
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);
        }
Пример #7
0
        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;
                }
            }
        }
Пример #8
0
        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;
        }
Пример #9
0
 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);
 }
Пример #10
0
            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;
            }
Пример #11
0
        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);
        }
Пример #12
0
 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);
 }
Пример #13
0
 /// <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);
 }
Пример #14
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);
 }
Пример #15
0
        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);
        }
Пример #16
0
 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);
 }
Пример #17
0
        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);
        }
Пример #18
0
        /// <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);
        }
Пример #19
0
        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);
        }
Пример #20
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);
        }
Пример #21
0
            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;
            }
Пример #22
0
        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;
                }
            }
        }
Пример #23
0
        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);
        }
Пример #24
0
        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));
        }
Пример #25
0
 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);
     }
 }
Пример #26
0
        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;
            }
        }
Пример #27
0
        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;
        }
Пример #28
0
        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;
            }
        }
Пример #29
0
            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;
            }
Пример #30
0
        /// <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));
        }
Пример #31
0
 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;
         }
     }
 }
Пример #32
0
 public k_PinnedNodeIterator(k_Tree ak_Tree, k_Node ak_Node)
     : base(ak_Tree, ak_Node)
 {
 }
Пример #33
0
 public void Clear()
 {
     mk_Head = mk_Tail = null;
     mk_Begin = mk_End;
     mi_Count = 0;
 }
Пример #34
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;
 }
Пример #35
0
            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;
            }
Пример #36
0
        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
            }
        }
Пример #37
0
            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;
            }
Пример #38
0
        /*
         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;
        }
Пример #39
0
        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;
            }
        }
Пример #40
0
 private bool IsRed(k_Node ak_Node)
 {
     return (ak_Node != null && ak_Node.Red);
 }
Пример #41
0
 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);
 }
Пример #42
0
        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;
                }
            }
        }
Пример #43
0
 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;
 }
Пример #44
0
        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);
        }
Пример #45
0
        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;
        }
Пример #46
0
 /// <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;
 }
Пример #47
0
        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;
        }
Пример #48
0
        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;
            }
        }
Пример #49
0
        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;
            }
        }
Пример #50
0
 public void Clear()
 {
     mi_Count = 0;
     mk_Head = null;
     mk_Left = null;
     mk_Right = null;
 }
Пример #51
0
 public k_NodeIterator(k_List ak_List, k_Node ak_Node)
 {
     mk_List = ak_List;
     mk_Current = ak_Node;
 }
Пример #52
0
        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;
        }
Пример #53
0
 public k_PinnedNodeIterator(k_List ak_List, k_Node ak_Node)
     : base(ak_List, ak_Node)
 {
 }
Пример #54
0
        // 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;
        }
Пример #55
0
            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;
            }
Пример #56
0
 public k_NodeIterator(k_Tree ak_Tree, k_Node ak_Node)
 {
     mk_Tree = ak_Tree;
     mk_Current = ak_Node;
 }
Пример #57
0
        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);
        }
Пример #58
0
 private k_Node Next(k_Node ak_Node)
 {
     return ak_Node.Next[0];
 }
Пример #59
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;
        }
Пример #60
0
 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;
 }