Is there a Lower Bound function on a SortedList<K ,V>?

agsamek picture agsamek · Feb 27, 2009 · Viewed 14.1k times · Source

Is there a Lower Bound function on a SortedList<K ,V>? The function should return the first element equal to or greater than the specified key. Is there some other class that supports this?

Guys - please read the question once again. I do not need a function that returns the key if it is present. I'm interested in scenario when there is no exact key matching.

I'm interested in O(log n) time. It means that I do not have a problem with foreach loop, but rather would like to have an efficient way of doing this.

I have done some tests on this.

Linq statements are not optimized by neither the compiler nor runtime machine, so they walk through all collection elements and are slow O(n). Based on Mehrdad Afshari answer, here is a Binary Search that works in O(log n) on the Keys collection:

public static int FindFirstIndexGreaterThanOrEqualTo<T>(
            this IList<T> sortedCollection, T key
        ) where T : IComparable<T> {
    int begin = 0;
    int end = sortedCollection.Count;
    while (end > begin) {
        int index = (begin + end) / 2;
        T el = sortedCollection[index];
        if (el.CompareTo(key) >= 0)
            end = index;
        else
            begin = index + 1;
    }
    return end;
}

Answer

mmx picture mmx · Feb 27, 2009

Binary search the SortedList.Keys collection.

Here we go. This is O(log n):

private static int BinarySearch<T>(IList<T> list, T value)
{
    if (list == null)
        throw new ArgumentNullException("list");
    var comp = Comparer<T>.Default;
    int lo = 0, hi = list.Count - 1;
    while (lo < hi) {
            int m = (hi + lo) / 2;  // this might overflow; be careful.
            if (comp.Compare(list[m], value) < 0) lo = m + 1;
            else hi = m - 1;
    }
    if (comp.Compare(list[lo], value) < 0) lo++;
    return lo;
}

public static int FindFirstIndexGreaterThanOrEqualTo<T,U>
                          (this SortedList<T,U> sortedList, T key)
{
    return BinarySearch(sortedList.Keys, key);
}