STL算法之sort

STL算法之sort

STL算的中的sort接受两个RandomAcceddIterators(随机存取迭代器)。STL的所有关系型容器都拥有自动排序功能(底层采用RB-tree),所有不需要用到sort算法。至于序列式容器stack,queue和priority-queue都有特别的出入口,不允许用户对元素排序。剩下的vector、deque和list,前两者的迭代器满足要求适合用sort算法。而list的迭代器属于BidirectionalIterators,不适合sort算法。如果要对list排序,可以使用它自己通过的成员函数sort()算法。

SGI STL的sort算法,数据量大时采用QuickSort,分段递归排序。一旦分段后的数据量小于某个门槛,为避免QuickSort的递归调用带来过大的额外负荷,就改用Insertion Sort。如果递归层次过深,还会改用Heap Sort。SGI将使用快排与插入排序的分割线设为16。

RW STL的sort算法,数据大的时候用QuickSort,小的时候用Insertion Sort。

下面是SGI STL sort的源码:

// 版本一
// 千萬注意:sort()只適用於 RandomAccessIterator
template <class RandomAccessIterator>
inline void sort(RandomAccessIterator first, RandomAccessIterator last) {
  if (first != last) {
    __introsort_loop(first, last, value_type(first), __lg(last - first) * 2);
    __final_insertion_sort(first, last);
  }
}

// 版本一
// 注意,本函式內的許多迭代器運算動作,都只適用於RandomAccess Iterators.
template <class RandomAccessIterator, class T, class Size>
void __introsort_loop(RandomAccessIterator first,
                      RandomAccessIterator last, T*,
                      Size depth_limit) {
  // 以下,__stl_threshold 是個全域常數,稍早定義為 const int 16。
  while (last - first > __stl_threshold) { 
    if (depth_limit == 0) {				// 至此,切割惡化
      partial_sort(first, last, last);	// 改用 heapsort
      return;
    }
    --depth_limit;
    // 以下是 median-of-three partition,選擇一個夠好的樞軸並決定切割點。
    // 切割點將落在迭代器 cut 身上。
    RandomAccessIterator cut = __unguarded_partition
      (first, last, T(__median(*first, *(first + (last - first)/2),
                               *(last - 1))));
    // 對右半段遞迴進行 sort.
    __introsort_loop(cut, last, value_type(first), depth_limit);
    last = cut;
    // 現在回到while 迴圈,準備對左半段遞迴進行 sort.
    // 這種寫法可讀性較差,效率並沒有比較好。
    // RW STL 採用一般教科書寫法(直觀地對左半段和右半段遞迴),較易閱讀。
  }
}
template <class RandomAccessIterator>
void __final_insertion_sort(RandomAccessIterator first, 
                            RandomAccessIterator last) {
  if (last - first > __stl_threshold) {
    __insertion_sort(first, first + __stl_threshold);
    __unguarded_insertion_sort(first + __stl_threshold, last);
  }
  else
    __insertion_sort(first, last);
}
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, 
                                  RandomAccessIterator 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 last, T value) {
  RandomAccessIterator next = last;
  --next;
  // insertion sort 的內迴圈
  // 注意,一旦不出現逆轉對(inversion),迴圈就可以結束了。
  while (value < *next) {	// 逆轉對(inversion)存在
    *last = *next;		// 轉正
    last = next;			// 調整迭代器
    --next;				// 前進一個位置
  }
  *last = value;
}
// 版本一
template <class RandomAccessIterator>
inline void __unguarded_insertion_sort(RandomAccessIterator first, 
                                RandomAccessIterator last) {
  __unguarded_insertion_sort_aux(first, last, value_type(first));
}
template <class RandomAccessIterator, class T>
void __unguarded_insertion_sort_aux(RandomAccessIterator first, 
                                    RandomAccessIterator last, T*) {
  for (RandomAccessIterator i = first; i != last; ++i)
    __unguarded_linear_insert(i, T(*i));
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值