How to perform a binary search on IList?

前端 未结 11 1269
执念已碎
执念已碎 2020-11-28 09:32

Simple question - given an IList how do you perform a binary search without writing the method yourself and without copying the data to a type with bui

相关标签:
11条回答
  • 2020-11-28 10:25

    You are going to have a couple of problems binary-searching an IList<T>, First ,like you mentioned, the BinarySearch method on the List<T> is not a member of the IList<T> interface. Second, you have no way of sorting the list prior to searching (which you must do for a binary search to work).

    I think your best bet is to create a new List<T>, sort it, and then search. It's not perfect but you don't have to many options if you have an IList<T>.

    0 讨论(0)
  • 2020-11-28 10:26

    Note that there is a bug in the implementation provided by Antoine below: when searching for an item greater than any in the list. The return value should be ~lower not ~middle. Decompile method ArraySortHelper.InternalBinarySearch (mscorlib) to see the framework implementation.

    0 讨论(0)
  • 2020-11-28 10:26

    Note that while List and IList do not have a BinarySearch method, SortedList does.

    0 讨论(0)
  • 2020-11-28 10:32

    I doubt there is a general purpose binary search method in .NET like that, except for the one being present in some base classes (but apparently not in the interfaces), so here's my general purpose one.

    public static Int32 BinarySearchIndexOf<T>(this IList<T> list, T value, IComparer<T> comparer = null)
    {
        if (list == null)
            throw new ArgumentNullException(nameof(list));
    
        comparer = comparer ?? Comparer<T>.Default;
    
        Int32 lower = 0;
        Int32 upper = list.Count - 1;
    
        while (lower <= upper)
        {
            Int32 middle = lower + (upper - lower) / 2;
            Int32 comparisonResult = comparer.Compare(value, list[middle]);
            if (comparisonResult == 0)
                return middle;
            else if (comparisonResult < 0)
                upper = middle - 1;
            else
                lower = middle + 1;
        }
    
        return ~lower;
    }
    

    This of course assumes that the list in question is already sorted, according to the same rules that the comparer will use.

    0 讨论(0)
  • 2020-11-28 10:32

    Keep in mind that binary search can be quite inefficient for some list implementations. For example, for a linked list it is O(n) if you implement it correctly, and O(n log n) if you implement it naively.

    0 讨论(0)
提交回复
热议问题