private static object GetComparerViaReflection(RangeTreeNode<int, RangeItem> rangeTreeNode)
 {
     var bindFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static;
     var comparerFieldInfo = typeof(RangeTreeNode<int, RangeItem>).GetField("_rangeComparer", bindFlags);
     var comparer = comparerFieldInfo.GetValue(rangeTreeNode);
     return comparer;
 }
Example #2
0
        private static object GetComparerViaReflection(RangeTreeNode <int, RangeItem> rangeTreeNode)
        {
            var bindFlags         = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static;
            var comparerFieldInfo = typeof(RangeTreeNode <int, RangeItem>).GetField("rangeComparer", bindFlags);
            var comparer          = comparerFieldInfo.GetValue(rangeTreeNode);

            return(comparer);
        }
Example #3
0
        /// <summary>
        /// Main build method, build a tree from a list of points, given that the nodes are sorted by last coordinate.
        /// </summary>
        /// <param name="rangeTreePoints">Points to store in new range tree. </param>
        /// <param name="sortingCoordinate">Sorting coordinate of new tree.</param>
        /// <returns>New balanced range tree.</returns>
        private RangeTreeNode <TValue> Build(List <ValueTuple <TValue, TValue> > rangeTreePoints, int sortingCoordinate)
        {
            if (rangeTreePoints.Count == 0)
            {
                return(null);
            }
            if (rangeTreePoints.Count == 1)
            {
                var node = new RangeTreeNode <TValue>(rangeTreePoints[0], Alpha, sortingCoordinate);
                return(node);
            }
            if (sortingCoordinate == 1)
            {
                // another y tree
                lastOpVisitedNodes += rangeTreePoints.Count;
                return(CreateBalancedTree(rangeTreePoints));
            }

            // find median, build its other dimension tree
            var medVal = rangeTreePoints.Median(xComparer);
            var median = new RangeTreeNode <TValue>(medVal, Alpha, 0);

            median.OtherDimensionSubtree = new RangeTree <TValue>(Build(new List <(TValue, TValue)>(rangeTreePoints), sortingCoordinate + 1), Alpha);

            // find nodes with same x-value, set is as middle nodes
            rangeTreePoints.Remove(medVal);
            var midsons = FindMiddleSons(rangeTreePoints, medVal, sortingCoordinate);

            median.SetMiddleSons(midsons);

            // split nodes by x-value of median
            var smallerInX = GetSmallerThanPoint(rangeTreePoints, medVal, xComparer);

            // build sons
            median.SetLeftSon(Build(smallerInX, sortingCoordinate));
            median.SetRightSon(Build(rangeTreePoints, sortingCoordinate));
            return(median);
        }
        private static IEnumerable<RangeTreeNode<int, RangeItem>> TraverseNode(RangeTreeNode<int, RangeItem> rangeTreeNode)
        {
            var bindFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static;
            var leftFieldInfo = typeof(RangeTreeNode<int, RangeItem>).GetField("_leftNode", bindFlags);
            var left = leftFieldInfo.GetValue(rangeTreeNode) as RangeTreeNode<int, RangeItem>;
            if (left != null)
            {
                yield return left;
                foreach (var node in TraverseNode(left))
                {
                    yield return node;
                }
            }

            var rightFieldInfo = typeof(RangeTreeNode<int, RangeItem>).GetField("_rightNode", bindFlags);
            var right = rightFieldInfo.GetValue(rangeTreeNode) as RangeTreeNode<int, RangeItem>;
            if (right != null)
            {
                yield return right;
                foreach (var node in TraverseNode(right))
                {
                    yield return node;
                }
            }
        }
Example #5
0
        /// <summary>
        /// Inserts a new value to tree.
        /// </summary>
        /// <param name="newvalue">2D point to be inserted</param>
        /// <param name="currentCoordinate">Current coordinate to navigate by</param>
        public void Insert(ValueTuple <TValue, TValue> newvalue, int currentCoordinate)
        {
            // for tree validity check
            //SaveLastState(OperationType.INSERT);
            lastOpVisitedNodes = 0;
            if (Root == null)
            {
                lastOpVisitedNodes = 1;
                Root = new RangeTreeNode <TValue>(newvalue, Alpha, currentCoordinate);
                return;
            }
            var comparer    = (currentCoordinate == 0) ? xComparer : yComparer;
            var currentNode = Root;
            var parent      = Root;

            // find a place for new leaf
            while (currentNode != null)
            {
                lastOpVisitedNodes++;
                parent = currentNode;
                if (currentCoordinate == 0)
                {
                    currentNode.OtherDimensionSubtree.Insert(newvalue, 1);
                }
                // greater
                if (comparer.Compare(newvalue, currentNode.Value) > 0)
                {
                    currentNode.SubtreeNodesCount++;
                    currentNode = currentNode.Right;
                }
                // lesser
                else if (comparer.Compare(newvalue, currentNode.Value) < 0)
                {
                    currentNode.SubtreeNodesCount++;
                    currentNode = currentNode.Left;
                }
                // equal
                else
                {
                    currentNode.AddMiddleSon(new RangeTreeNode <TValue>(newvalue, Alpha, currentCoordinate));
                    // we are done here, this cannot break the invariant
                    return;
                }
            }

            // add the new leaf
            RangeTreeNode <TValue> leaf = new RangeTreeNode <TValue>(newvalue, Alpha, currentCoordinate);

            if (comparer.Compare(parent.Value, newvalue) > 0)
            {
                parent.SetLeftSon(leaf);
            }
            else
            {
                parent.SetRightSon(leaf);
            }
            parent.SubtreeNodesCount--;

            // rebuild the unbalanced trees
            currentNode = parent;
            while (currentNode != null)
            {
                if (!currentNode.IsBalanced())
                {
                    var nodes = QuickSort <TValue> .Sort(currentNode.GetSubtreeValuesInOrder(), yComparer);

                    var rebuild = Build(nodes, currentCoordinate);
                    // for x and y tree
                    lastOpVisitedNodes += (rebuild.SubtreeNodesCount);
                    // we rebuit entire tree
                    if (currentNode.Parent == null)
                    {
                        Root        = rebuild;
                        currentNode = rebuild;
                    }
                    else
                    {
                        if (comparer.Compare(currentNode.Parent.Value, rebuild.Value) > 0)
                        {
                            currentNode.Parent.SetLeftSon(rebuild);
                        }
                        else
                        {
                            currentNode.Parent.SetRightSon(rebuild);
                        }
                    }
                }
                currentNode = currentNode.Parent;
            }
        }
Example #6
0
 /// <summary>
 /// Constructor using a given tree (used for Node-Tree conversion).
 /// </summary>
 /// <param name="root">Root of new tree.</param>
 /// <param name="alpha">Alpha of BB-alpha trees implementing range tree</param>
 public RangeTree(RangeTreeNode <TValue> root, double alpha)
 {
     Root  = root;
     Alpha = alpha;
 }