• STL 源代码剖析 算法 stl_algo.h -- nth_element


    本文为senlie原创。转载请保留此地址:http://blog.csdn.net/zhengsenlie


    nth_element
    ------------------------------------------------------------------------------


    描写叙述:又一次排序,使得[nth,last)内没有不论什么一个元素小于[first,nth)内的元素,
    但对于[first,nth)和[nth,last)两个子区间内的元素次序则无不论什么保证。
    思路:
    1.以 median-of-3-partition 将整个序列切割为更小的左、右子序列
    2.假设 nth 迭代器落于左序列,就再对左子序列进行切割,否则就再对右子序列进行切割
    3.直到切割后的子序列长大于3,对最后这个待切割的子序列做 Insertion Sort

    复杂度:O(n)
    源代码:

    template <class RandomAccessIterator>
    inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth,
                            RandomAccessIterator last) {
      __nth_element(first, nth, last, value_type(first));
    }
    
    
    template <class RandomAccessIterator, class T>
    void __nth_element(RandomAccessIterator first, RandomAccessIterator nth,
                       RandomAccessIterator last, T*) {
      while (last - first > 3) {
        //採用 median-of-3-partition 。參数:(first,last,pivot)
    	//返回一个迭代器,指向切割后的右段第一个元素
    	RandomAccessIterator cut = __unguarded_partition
          (first, last, T(__median(*first, *(first + (last - first)/2),
                                   *(last - 1))));
        if (cut <= nth) //假设  nth 落于右段,再对右段实施切割
          first = cut;
        else  //假设 nth 落于左段。对左段实施切割
          last = cut;
      }
      __insertion_sort(first, last); //对切割后的子序列做 Insertion Sort
    }
    
    
    template <class RandomAccessIterator, class T>
    RandomAccessIterator __unguarded_partition(RandomAccessIterator first, 
                                               RandomAccessIterator last, 
                                               T pivot) {
      while (true) {
        while (*first < pivot) ++first;
        --last;
        while (pivot < *last) --last;
        if (!(first < last)) return first;
        iter_swap(first, last);
        ++first;
      }
    }    
    

    演示样例:
    int A[] = {7, 2, 6, 11, 9, 3, 12, 10, 8, 4, 1, 5};
    const int N = sizeof(A) / sizeof(int);
    
    
    nth_element(A, A + 6, A + N);
    copy(A, A + N, ostream_iterator<int>(cout, " "));
    // The printed result is "5 2 6 1 4 3 7 8 9 10 11 12".


  • 相关阅读:
    百度地图学习
    JS中call和apply区别有哪些 记录
    初次学习AngularJS
    C#中Abstract和Virtua笔记,知识
    css学习笔记四
    css学习笔记三
    jquery基础 笔记三
    jquery基础 笔记二
    jquery基础 笔记一
    负边距在布局中的应用
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5254745.html
Copyright © 2020-2023  润新知