Esempio n. 1
0
        /// <summary>
        /// Initializes an empty node.
        /// </summary>
        /// <param name="rangeComparer">The comparer used to compare two items.</param>
        public RangeTreeNode(IComparer <T> rangeComparer = null)
        {
            if (rangeComparer != null)
            {
                _sRangeComparer = rangeComparer;
            }

            _center    = default;
            _leftNode  = null;
            _rightNode = null;
            _items     = null;
        }
Esempio n. 2
0
        /// <summary>
        /// Initializes a node with a list of items, builds the sub tree.
        /// </summary>
        /// <param name="items">Items collection</param>
        /// <param name="rangeComparer">The comparer used to compare two items.</param>
        public RangeTreeNode(IEnumerable <T> items, IComparer <T> rangeComparer = null)
        {
            if (rangeComparer != null)
            {
                _sRangeComparer = rangeComparer;
            }

            // first, find the median
            var endPoints  = new List <TKey>();
            var itemsArray = items as T[] ?? items.ToArray();

            foreach (var o in itemsArray)
            {
                var range = o.Range;
                endPoints.Add(range.From);
                endPoints.Add(range.To);
            }
            endPoints.Sort();

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

            var left  = new List <T>();
            var right = new List <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 itemsArray)
            {
                var range = o.Range;

                if (range.To.CompareTo(_center) < 0)
                {
                    left.Add(o);
                }
                else if (range.From.CompareTo(_center) > 0)
                {
                    right.Add(o);
                }
                else
                {
                    _items.Add(o);
                }
            }

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

            // create left and right nodes, if there are any items
            if (left.Count > 0)
            {
                _leftNode = new RangeTreeNode <TKey, T>(left);
            }
            if (right.Count > 0)
            {
                _rightNode = new RangeTreeNode <TKey, T>(right);
            }
        }