예제 #1
0
        internal T Index(int index)
        {
            if (index < 0 || index >= Length)
            {
                throw new IndexOutOfRangeException(nameof(index));
            }
            TreapNode current        = this.Root;
            int       chunkBeginning = 0;

            while (true)
            {
                int leftSubtreeSize = TreapNode.GetSize(current.LChild);
                if (index < leftSubtreeSize)
                {
                    current = current.LChild;
                }
                else
                {
                    chunkBeginning += leftSubtreeSize;
                    index          -= leftSubtreeSize;

                    if (index < current.Length)
                    {
                        return(current.Data[current.Offset + index]);
                    }
                    else
                    {
                        chunkBeginning += current.Length;
                        index          -= current.Length;
                        current         = current.RChild;
                    }
                }
            }
        }
예제 #2
0
        internal void Split(TreapNode node, int index, out TreapNode L, out TreapNode R)
        {
            TreapNode newTree = null;
            int       lBound  = TreapNode.GetSize(node.LChild);
            int       rBound  = lBound + node.Size;

            if (index >= rBound) // going right
            {
                if (node.RChild == null)
                {
                    R = null;
                }
                else
                {
                    Split(node.RChild, index - rBound, out newTree, out R);
                }

                L = new TreapNode(node.Data, node.Offset, node.Length, node.Priority, node.LChild, newTree);
            }
            else if (index < lBound) // going left
            {
                if (node.LChild == null)
                {
                    L = null;
                }
                else
                {
                    Split(node.LChild, index, out L, out newTree);
                }

                R = new TreapNode(node.Data, node.Offset, node.Length, node.Priority, newTree, node.RChild);
            }
            else // split node in middle
            {
                index -= lBound;
                L      = new TreapNode(
                    data: node.Data,
                    offset: node.Offset,
                    length: index,
                    priority: RandomGenerator.Next(),
                    left: node.LChild,
                    right: null
                    );
                R = new TreapNode(
                    data: node.Data,
                    offset: node.Offset + index,
                    length: node.Length - index,
                    priority: RandomGenerator.Next(),
                    left: null,
                    right: node.RChild
                    );
            }
        }
예제 #3
0
        private void SplitStack(TreapNode node, int index, out TreapNode L, out TreapNode R)
        {
            Stack <TreapNode> path = new Stack <TreapNode>();

            while (true)
            {
                path.Push(node);

                int leftBound  = TreapNode.GetSize(node.LChild);
                int rightBound = leftBound + node.Size;

                if (index < leftBound) // going left
                {
                    node = node.LChild;
                }
                else if (rightBound <= index) // going right
                {
                    node = node.RChild;
                }
                else // split node
                {
                    L = new TreapNode(
                        data: node.Data,
                        offset: node.Offset,
                        length: index,
                        priority: RandomGenerator.Next(),
                        left: node.LChild,
                        right: null
                        );
                    R = new TreapNode(
                        data: node.Data,
                        offset: node.Offset + index,
                        length: node.Length - index,
                        priority: RandomGenerator.Next(),
                        left: null,
                        right: node.RChild
                        );
                    break;
                }
            }

            Console.Error.WriteLine(string.Join("\n", path.Reverse()));

            while (path.Count > 0)
            {
                var currentNode = path.Pop();
            }
        }