Пример #1
0
        public void Add(T item)
        {
            SaveTree();
            int size = LeftSize;

            RBNode <T> node = LeftChild;

            if (node == null)
            {
                node = InsertNode(0);
                node.InsertAt(0, item);
            }
            else
            {
                while (node.RightChild != null)
                {
                    node = node.RightChild;
                }
                if (node.Size < MaxSize)
                {
                    node.InsertAt(node.Size, item);
                }
                else
                {
                    node = InsertNode(this.LeftSize);
                    node.InsertAt(0, item);
                }
            }

            LeftChild.IsRed = false;
            Verify(size + 1, false);
        }
Пример #2
0
        // move the item under oldFinger to newFinger (assumed to be left of oldFinger)
        protected void ReInsert(ref RBFinger <T> oldFinger, RBFinger <T> newFinger)
        {
            RBNode <T> oldNode = oldFinger.Node, newNode = newFinger.Node;
            int        oldOffset = oldFinger.Offset, newOffset = newFinger.Offset;
            T          x = oldNode.GetItemAt(oldFinger.Offset);

            if (oldNode == newNode)
            {   // move within a single node
                int s = oldOffset - newOffset;

                if (s != 0)
                {
                    Copy(oldNode, newOffset, oldNode, newOffset + 1, s);
                    oldNode.SetItemAt(newOffset, x);
                }
            }
            else
            {     // move from one node to an earlier node
                if (newNode.Size < MaxSize)
                { // easy case - new node has room
                    newNode.InsertAt(newOffset, x);
                    oldNode.RemoveAt(ref oldFinger);
                }
                else
                {   // hard case - new node is full
                    RBNode <T> successor = newNode.GetSuccessor();
                    if (successor == oldNode)
                    {   // easy subcase - oldNode is next to newNode
                        T y = newNode.GetItemAt(MaxSize - 1);
                        Copy(newNode, newOffset, newNode, newOffset + 1, MaxSize - newOffset - 1);
                        newNode.SetItemAt(newOffset, x);
                        Copy(oldNode, 0, oldNode, 1, oldOffset);
                        oldNode.SetItemAt(0, y);
                    }
                    else
                    {
                        if (successor.Size < MaxSize)
                        {   // medium subcase - need to move items into successor
                            newNode.InsertAt(newOffset, x, successor);
                        }
                        else
                        {   // hard subcase - need a new node after newNode
                            RBNode <T> succsucc = successor;
                            successor = InsertNodeAfter(newNode);
                            newNode.InsertAt(newOffset, x, successor, succsucc);
                        }

                        oldNode.RemoveAt(ref oldFinger);
                    }
                }
            }
        }
Пример #3
0
        // Token: 0x06007691 RID: 30353 RVA: 0x0021DF78 File Offset: 0x0021C178
        protected void ReInsert(ref RBFinger <T> oldFinger, RBFinger <T> newFinger)
        {
            RBNode <T> node    = oldFinger.Node;
            RBNode <T> node2   = newFinger.Node;
            int        offset  = oldFinger.Offset;
            int        offset2 = newFinger.Offset;
            T          itemAt  = node.GetItemAt(oldFinger.Offset);

            if (node == node2)
            {
                int num = offset - offset2;
                if (num != 0)
                {
                    this.Copy(node, offset2, node, offset2 + 1, num);
                    node.SetItemAt(offset2, itemAt);
                    return;
                }
            }
            else
            {
                if (node2.Size < 64)
                {
                    node2.InsertAt(offset2, itemAt, null, null);
                    node.RemoveAt(ref oldFinger);
                    return;
                }
                RBNode <T> rbnode = node2.GetSuccessor();
                if (rbnode == node)
                {
                    T itemAt2 = node2.GetItemAt(63);
                    this.Copy(node2, offset2, node2, offset2 + 1, 64 - offset2 - 1);
                    node2.SetItemAt(offset2, itemAt);
                    this.Copy(node, 0, node, 1, offset);
                    node.SetItemAt(0, itemAt2);
                    return;
                }
                if (rbnode.Size < 64)
                {
                    node2.InsertAt(offset2, itemAt, rbnode, null);
                }
                else
                {
                    RBNode <T> succsucc = rbnode;
                    rbnode = this.InsertNodeAfter(node2);
                    node2.InsertAt(offset2, itemAt, rbnode, succsucc);
                }
                node.RemoveAt(ref oldFinger);
            }
        }
Пример #4
0
        void Insert(RBFinger <T> finger, T x, bool checkSort = false)
        {
#if RBTreeFlightRecorder
            SaveTree();
            int size = LeftSize;
#endif

            RBNode <T> node = finger.Node;

            if (node == this)
            {
                node = InsertNode(0);
                node.InsertAt(0, x);
            }
            else if (node.Size < MaxSize)
            {
                node.InsertAt(finger.Offset, x);
            }
            else
            {
                RBNode <T> successor = node.GetSuccessor();
                RBNode <T> succsucc  = null;
                if (successor.Size >= MaxSize)
                {
                    if (successor != this)
                    {
                        succsucc = successor;
                    }
                    successor = InsertNode(finger.Index + node.Size - finger.Offset);
                }
                node.InsertAt(finger.Offset, x, successor, succsucc);
            }

            LeftChild.IsRed = false;

#if RBTreeFlightRecorder
            Verify(size + 1, checkSort);
#endif
        }
Пример #5
0
        internal void InsertAt(int offset, T x, RBNode <T> successor = null, RBNode <T> succsucc = null)
        {
            if (Size < MaxSize)
            {
                // insert x into this.Array at offset
                Copy(this, offset, this, offset + 1, Size - offset);
                SetItemAt(offset, x);
                ChangeSize(1);
            }
            else
            {
                Debug.Assert(successor != null && successor.Size < MaxSize, "InsertAt: successor should have room");
                if (successor.Size == 0)
                {
                    if (succsucc == null)
                    {   // special case for insertion at the right - keep this node full
                        if (offset < MaxSize)
                        {
                            // move last item to successor
                            successor.InsertAt(0, GetItemAt(MaxSize - 1));
                            // insert x into this.Array at offset
                            Copy(this, offset, this, offset + 1, MaxSize - offset - 1);
                            SetItemAt(offset, x);
                        }
                        else
                        {
                            // insert x into successor
                            successor.InsertAt(0, x);
                        }
                    }
                    else
                    {   // split two full nodes into three
                        Debug.Assert(succsucc.Size == MaxSize, "InsertAt: outer nodes should be full");
                        int s = MaxSize / 3;

                        // move s items from this node into successor
                        Copy(successor, 0, successor, s, successor.Size);
                        Copy(this, MaxSize - s, successor, 0, s);

                        // move s items from succsucc into successor
                        Copy(succsucc, 0, successor, s + successor.Size, s);
                        Copy(succsucc, s, succsucc, 0, MaxSize - s);

                        if (offset <= MaxSize - s)
                        {
                            // insert into this.Array at offset
                            Copy(this, offset, this, offset + 1, MaxSize - s - offset);
                            SetItemAt(offset, x);

                            this.ChangeSize(1 - s);
                            successor.ChangeSize(s + s);
                        }
                        else
                        {
                            // insert into successor.Array at offset-(MaxSize-s)
                            Copy(successor, offset - (MaxSize - s), successor, offset - (MaxSize - s) + 1, successor.Size + s + s - (offset - (MaxSize - s)));
                            successor.SetItemAt(offset - (MaxSize - s), x);

                            this.ChangeSize(-s);
                            successor.ChangeSize(s + s + 1);
                        }
                        succsucc.ChangeSize(-s);
                    }
                }
                else
                {   // split a full node and its not-full successor into two pieces
                    int s = (Size + successor.Size + 1) / 2;

                    if (offset < s)
                    {
                        // move MaxSize-s+1 items from this node into successor
                        Copy(successor, 0, successor, MaxSize - s + 1, successor.Size);
                        Copy(this, s - 1, successor, 0, MaxSize - s + 1);

                        // insert into this.Array at offset
                        Copy(this, offset, this, offset + 1, s - 1 - offset);
                        SetItemAt(offset, x);
                    }
                    else
                    {
                        // move MaxSize-s items from this node into successor
                        Copy(successor, 0, successor, MaxSize - s, successor.Size);
                        Copy(this, s, successor, 0, MaxSize - s);

                        // insert into successor.Array at offset-s
                        Copy(successor, offset - s, successor, offset - s + 1, successor.Size + MaxSize - offset);
                        successor.SetItemAt(offset - s, x);
                    }
                    this.ChangeSize(s - MaxSize);
                    successor.ChangeSize(MaxSize - s + 1);
                }
            }
        }
Пример #6
0
 // Token: 0x06007696 RID: 30358 RVA: 0x0021E1A8 File Offset: 0x0021C3A8
 internal void InsertAt(int offset, T x, RBNode <T> successor = null, RBNode <T> succsucc = null)
 {
     if (this.Size < 64)
     {
         this.Copy(this, offset, this, offset + 1, this.Size - offset);
         this.SetItemAt(offset, x);
         this.ChangeSize(1);
         return;
     }
     if (successor.Size != 0)
     {
         int num = (this.Size + successor.Size + 1) / 2;
         if (offset < num)
         {
             this.Copy(successor, 0, successor, 64 - num + 1, successor.Size);
             this.Copy(this, num - 1, successor, 0, 64 - num + 1);
             this.Copy(this, offset, this, offset + 1, num - 1 - offset);
             this.SetItemAt(offset, x);
         }
         else
         {
             this.Copy(successor, 0, successor, 64 - num, successor.Size);
             this.Copy(this, num, successor, 0, 64 - num);
             this.Copy(successor, offset - num, successor, offset - num + 1, successor.Size + 64 - offset);
             successor.SetItemAt(offset - num, x);
         }
         this.ChangeSize(num - 64);
         successor.ChangeSize(64 - num + 1);
         return;
     }
     if (succsucc != null)
     {
         int num2 = 21;
         this.Copy(successor, 0, successor, num2, successor.Size);
         this.Copy(this, 64 - num2, successor, 0, num2);
         this.Copy(succsucc, 0, successor, num2 + successor.Size, num2);
         this.Copy(succsucc, num2, succsucc, 0, 64 - num2);
         if (offset <= 64 - num2)
         {
             this.Copy(this, offset, this, offset + 1, 64 - num2 - offset);
             this.SetItemAt(offset, x);
             this.ChangeSize(1 - num2);
             successor.ChangeSize(num2 + num2);
         }
         else
         {
             this.Copy(successor, offset - (64 - num2), successor, offset - (64 - num2) + 1, successor.Size + num2 + num2 - (offset - (64 - num2)));
             successor.SetItemAt(offset - (64 - num2), x);
             this.ChangeSize(-num2);
             successor.ChangeSize(num2 + num2 + 1);
         }
         succsucc.ChangeSize(-num2);
         return;
     }
     if (offset < 64)
     {
         successor.InsertAt(0, this.GetItemAt(63), null, null);
         this.Copy(this, offset, this, offset + 1, 64 - offset - 1);
         this.SetItemAt(offset, x);
         return;
     }
     successor.InsertAt(0, x, null, null);
 }