Esempio n. 1
0
        /// <summary>
        /// Initializes a tree with a list of items to be added.
        /// </summary>
        public RangeTree(IEnumerable <IInterval <T> > items, IComparer <IInterval <T> > rangeComparer = null)
        {
            this._rangeComparer = rangeComparer ?? Comparer <IInterval <T> > .Default;
            this._items         = items != null?items.ToList() : new List <IInterval <T> >();

            this._root        = new RangeTreeNode <T>(this._items, rangeComparer);
            this._isInSync    = true;
            this._autoRebuild = true;
        }
Esempio n. 2
0
        /// <summary>
        /// Rebuilds the tree if it is out of sync.
        /// </summary>
        public void Rebuild()
        {
            if (this._isInSync)
            {
                return;
            }

            this._root     = new RangeTreeNode <T>(this._items, this._rangeComparer);
            this._isInSync = true;
        }
Esempio n. 3
0
        /// <summary>
        /// Initializes a node with a list of items, builds the sub tree.
        /// </summary>
        /// <param name="items">Data to include in this node.</param>
        /// <param name="rangeComparer">The comparer used to compare two items.</param>
        public RangeTreeNode(IEnumerable <IInterval <T> > items, IComparer <IInterval <T> > rangeComparer = null)
        {
            rangeComparer = rangeComparer ?? Comparer <IInterval <T> > .Default;

            // No items? nothing to do
            if (items == null || !items.Any())
            {
                return;
            }

            // first, find the median
            var endPoints = new List <T>();

            foreach (var o in items)
            {
                var range = o;
                endPoints.Add(range.Min.Value);
                endPoints.Add(range.Max.Value);
            }
            endPoints.Sort();

            // the median is used as center value
            this._center = endPoints[endPoints.Count / 2];
            this._items  = new List <IInterval <T> >();

            var left  = new List <IInterval <T> >();
            var right = new List <IInterval <T> >();

            // iterate over all items
            // if the range of an item is completely left of the center, add it to the left items
            // if it is on the right of the center, add it to the right items
            // otherwise (range overlaps the center), add the item to this node's items
            foreach (var o in items)
            {
                var range = o;

                if (range.Max.Value.CompareTo(this._center) < 0)
                {
                    left.Add(o);
                }
                else if (range.Min.Value.CompareTo(this._center) > 0)
                {
                    right.Add(o);
                }
                else
                {
                    this._items.Add(o);
                }
            }

            // sort the items, this way the query is faster later on
            if (this._items.Count > 0)
            {
                this._items.Sort(rangeComparer);
            }
            else
            {
                this._items = null;
            }

            // create left and right nodes, if there are any items
            if (left.Count > 0)
            {
                this._leftNode = new RangeTreeNode <T>(left);
            }
            if (right.Count > 0)
            {
                this._rightNode = new RangeTreeNode <T>(right);
            }
        }
Esempio n. 4
0
 /// <summary>
 /// Clears the tree (removes all items).
 /// </summary>
 public void Clear()
 {
     this._root     = new RangeTreeNode <T>(this._rangeComparer);
     this._items    = new List <IInterval <T> >();
     this._isInSync = true;
 }