当前位置:C++技术网 > 资讯 > FCL源码中数组类型的学习及排序函数Sort函数的分析

FCL源码中数组类型的学习及排序函数Sort函数的分析

更新时间:2017-10-17 08:43:30浏览次数:1+次

Array 是所有数组的基类
ArrayList 解决了所有Array 类的缺点    能动态扩容, 但是类型不安全的,而是会有装箱与拆箱的性能开销
List<T> 则是解决了ArrayList 类的装箱,拆箱问题, 能够动态扩容,但是所有的顺序结构数据结构的缺点就是数据空间的开辟开销
这三个类都是基于数组实现的, 并没有用到链表的实现.
具体的源码可以通过.NET Reflector 来看。对于内置函数Sort 我一直比较好奇,分析着它的实现应该是快排实现的,分析了下List<T> 的Sort 函数,先看看源码:

代码:
private static void IntroSort(T[] keys, int lo, int hi, int depthLimit, IComparer<T> comparer)
{
    while (hi > lo)
    {
        int num = (hi - lo) + 1;
        if (num <= 0x10)
        {
            switch (num)
            {
                case 1:
                    return;

                case 2:
                    ArraySortHelper<T>.SwapIfGreater(keys, comparer, lo, hi);
                    return;

                case 3:
                    ArraySortHelper<T>.SwapIfGreater(keys, comparer, lo, hi - 1);
                    ArraySortHelper<T>.SwapIfGreater(keys, comparer, lo, hi);
                    ArraySortHelper<T>.SwapIfGreater(keys, comparer, hi - 1, hi);
                    return;
            }
            ArraySortHelper<T>.InsertionSort(keys, lo, hi, comparer);
            return;
        }
        if (depthLimit == 0)
        {
            ArraySortHelper<T>.Heapsort(keys, lo, hi, comparer);
            return;
        }
        depthLimit--;
        int num2 = ArraySortHelper<T>.PickPivotAndPartition(keys, lo, hi, comparer);
        ArraySortHelper<T>.IntroSort(keys, num2 + 1, hi, depthLimit, comparer);
        hi = num2 - 1;
    }
}
FCL的数组类中 内置了专门用来处理排序的一个类 ArraySortHelper<T>。
数组类型的数据结构(不管是List, ArrayList, Array)其Sort 排序函数都是基于ArraySortHelper<T> Sort 函数来排序的。
该函数主要涉及到三种排序算法: 快排, 插入排序, 堆排序, 内省排序
排序数字小于16个,直接使用插入排序
递归深度在32次之内(数字小于4GB)采用快排
大于4GB,则堆排序

看了下源码,不得不佩服那些大神写的框架源码,那些最基本的数据结构和算法在底层的应用这么广,起了这么大的作用,是我们平常使用的函数的基础。

参考: Introsort(内观排序) (http://www.cnblogs.com/johnwu/p/3344935.html)