/// <summary> /// Initializes an empty tree. /// </summary> public RangeTree(IComparer <T> rangeComparer) { _rangeComparer = rangeComparer; _root = new RangeTreeNode <TKey, T>(rangeComparer); _items = new List <T>(); _isInSync = true; _autoRebuild = true; }
/// <summary> /// Initializes a tree with a list of items to be added. /// </summary> public RangeTree(IEnumerable <T> items, IComparer <T> rangeComparer) { _rangeComparer = rangeComparer; _root = new RangeTreeNode <TKey, T>(items, rangeComparer); _items = items.ToList(); _isInSync = true; _autoRebuild = true; }
/// <summary> /// Rebuilds the tree if it is out of sync. /// </summary> public void Rebuild() { if (_isInSync) { return; } _root = new RangeTreeNode <TKey, T>(_items, _rangeComparer); _isInSync = true; }
/// <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) { s_rangeComparer = rangeComparer; } _center = default(TKey); _leftNode = null; _rightNode = null; _items = null; }
/// <summary> /// Clears the tree (removes all items). /// </summary> public void Clear() { _root = new RangeTreeNode <TKey, T>(_rangeComparer); _items = new List <T>(); _isInSync = true; }
/// <summary> /// Initializes a node with a list of items, builds the sub tree. /// </summary> /// <param name="items">The itme is added</param> /// <param name="rangeComparer">The comparer used to compare two items.</param> public RangeTreeNode(IEnumerable <T> items, IComparer <T> rangeComparer = null) { if (rangeComparer != null) { s_rangeComparer = rangeComparer; } // first, find the median var endPoints = new List <TKey>(); foreach (var o in items) { 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 items) { 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(s_rangeComparer); } 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); } }