SortedList

SortedList 表示键/值对的集合,这些键/值对基于关联的 System.Collections.Generic.IComparer<T> 实现按照键进行升序排序

public class SortedList<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IDictionary, ICollection, IEnumerable

其内部维护了两个动态数组keys[],values[],每增加一个新的元素时,调用排序方法找到新增key的顺序位置,然后插入,如有重复key则抛出exception,其排序方法基于二分法排序:

public virtual void Add(object key, object value)
{
    if (key == null)
    {
        throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));
    }
    int index = Array.BinarySearch(this.keys, 0, this._size, key, this.comparer);
    if (index >= 0)
    {
        throw new ArgumentException(Environment.GetResourceString("Argument_AddingDuplicate__", new object[] { this.GetKey(index), key }));
    }
    this.Insert(~index, key, value);
}

Array.BinarySearch为二分查找法,源码实现如下,:

public static int BinarySearch(Array array, int index, int length, object value, IComparer comparer)
{
    int num2;
    if (array == null)
    {
        throw new ArgumentNullException("array");
    }
    int lowerBound = array.GetLowerBound(0);
    if ((index < lowerBound) || (length < 0))
    {
        throw new ArgumentOutOfRangeException((index < lowerBound) ? "index" : "length", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
    }
    if ((array.Length - (index - lowerBound)) < length)
    {
        throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
    }
    if (array.Rank != 1)
    {
        throw new RankException(Environment.GetResourceString("Rank_MultiDimNotSupported"));
    }
    if (comparer == null)
    {
        comparer = Comparer.Default;
    }
    if ((comparer == Comparer.Default) && TrySZBinarySearch(array, index, length, value, out num2))
    {
        return num2;
    }
    int low = index;
    int hi = (index + length) - 1;
    object[] objArray = array as object[];
    if (objArray == null)
    {
        while (low <= hi)
        {
            int num8;
            int median = GetMedian(low, hi);
            try
            {
                num8 = comparer.Compare(array.GetValue(median), value);
            }
            catch (Exception exception2)
            {
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), exception2);
            }
            if (num8 == 0)
            {
                return median;
            }
            if (num8 < 0)
            {
                low = median + 1;
            }
            else
            {
                hi = median - 1;
            }
        }
    }
    else
    {
        while (low <= hi)
        {
            int num6;
            int num5 = GetMedian(low, hi);
            try
            {
                num6 = comparer.Compare(objArray[num5], value);
            }
            catch (Exception exception)
            {
                throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), exception);
            }
            if (num6 == 0)
            {
                return num5;
            }
            if (num6 < 0)
            {
                low = num5 + 1;
            }
            else
            {
                hi = num5 - 1;
            }
        }
    }
    return ~low;
}
原文地址:https://www.cnblogs.com/Finding2013/p/3047525.html