• 《STL源码剖析》Sort排序分析


    整体而言: sort算法在数据量大时采用Quick Sort(快速排序),一旦分段后的数据量小于某个门槛,为避免Quick Sort的递归调用带来过大的额外负担,就改用Insertion Sort(插入排序),如果递归层次过深,还会改用Heap Sort(堆排序),先分别简单介绍Quick Sort

    Insertion Sort插入排序

    Insertion sort以双层循环的形式进行,外循环便利整个序列,每次迭代决定出一个自区间,内循环遍历自区间,将自区间内的没一个“逆转对”倒转过来。所谓“逆转对”是指任何两个迭代器i,j,i

    template<class RandomAccessIterator>
    void __insertion_sort(RandomAccessIterator first,RandomAccessIterator last){
        if(first==last) return;
        for(RandomAccessIterator i=first+1;i!=last;++i)//外循环
            __linear_insert(first,i,value_type(first));
            //以上[first,i)形成一个子区间
    }
    
    template <class RandomAccessIterator,class T>
    inline void__linear_insert(RandomAccessIterator first,Random AccessIterator last,T*){
        T value=*last;//记录尾元素
        if(value<*first){
        copy_backward(first,last,last+1);//将整个区间拷贝
        *first=value;
        }
        else//尾不小于头
        __unguarded_linear_insert(last,value);
    }
    
    template<class RandomAccessIterator,class T>
    void __unguarded_linear_insert(RandomAccessIterator first,Random AccessIterator last,T value){
        RandomAccessIterator next=last;
        --next;
        //insertion sort的内循环
        //注意,一旦不再出现逆转对,循环就可以结束了
        while(value<*next){//逆转对存在
        *last==*next;
        last=nex;
        --next;
        }
        *last=value;
    }

    Quick Sort快速排序

    Quick Sort是目前已知的最快的排序法,平均复杂度为O(NlogN),最坏情况下将达O(N²)。不过IntroSort(非常类似于median-of-three QuickSort的一种排序算法)可将最坏情况推进到O(NlogN)。早期的STLsort算法都采用QuickSort,SGI STL已经改用IntroSort。
    median-of-three(三点之中值):任意一个元素都可以被送来当枢轴(pivot),但其合适与否将影响QuickSort的效率,为了避免“元素当初输入时不够随机”所带来的恶化效应,最理想的最稳当的方法就是取整个序列的头、尾、中央三个位置的元素,以其中值作为枢轴,这种做法成为median-of-three partitioning,或成为median-of-QuickSort,为了能够快速取出中央位置的元素,显然迭代器必须能够快速取出中央位置的元素,显然迭代器必须能够随机读取,亦即是个RandomAccessIterators。

    final insertion sort

    sort采用的优化方案,即前面的所有排序步骤都采用QuickSOrt,只有最后一次采用insertionSort,因为insertionSort在面对“几近排序”的序列时,能拥有很好的表现。

    Inrtosort(Introspective sorting,内省式排序)

    其行为在大部分情况下几乎与median-of-three Quick Sort完全相同(当然也就一样快,但是当分割行为有恶化为二次行为的倾向时,能够自我检测,转而改用Heap Sort,使得效率维持在HeapSort的O(NlogN),又比一开始就用HeapSort来得好。

    https://github.com/li-zheng-hao
  • 相关阅读:
    MovieLens
    牛顿法与拟牛顿法学习笔记(一)牛顿法
    Softmax回归
    PCA练习
    PCA主成分分析
    算法——A*——HDOJ:1813
    spring 入门篇
    java——多线程——单例模式的static方法和非static方法是否是线程安全的?
    java——数据库——commons-DbUtils
    java——HashCode和equal方法
  • 原文地址:https://www.cnblogs.com/lizhenghao126/p/11053749.html
Copyright © 2020-2023  润新知