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; } } } }
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 ); } }
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(); } }