今天又看了一遍sort源码,忽然发现一个问题:
template<typename _RandomAccessIterator, typename _Compare>
inline _RandomAccessIterator
__unguarded_partition_pivot(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Compare __comp) {
_RandomAccessIterator __mid = __first + (__last - __first) / 2;//@看这里!!!
std::__move_median_to_first(__first, __first + 1, __mid, __last - 1,
__comp);
return std::__unguarded_partition(__first + 1, __last, __first, __comp);
}
代码中注释所在的那一行,二分枢纽取了数组中间位置的值,数据结构知识告诉我们这么随意的取值可能导致sort性能下降,于是我将其取枢纽代码改了一下:
//原来是这样
_RandomAccessIterator __mid = __first + (__last - __first) / 2;
//改成这样>>>
template <class T>
inline const T& __median(const T& a, const T& b, const T& c) {
if( a < b ) {
if( b < c ) //a<b<c
return b;
else if( a < c) // a < b, b >= c, a<c
return c;
else
return a;
} else if( a < c) // c > a >= b
return a;
else if( b < c) // a >= b, a >= c, b < c
return c;
else
return b;
}
_RandomAccessIterator __mid = __median(__first,__first + (__last - __first),__last);
也就是把取中间位置的元素作为枢纽
改成了取首、中、尾三位置的中间值作为枢纽
。测试了一下,发现效率提高百分之七左右,当然我的测试并不完善,此改动的效果还需要在实践中去探索。
没想到gccSTL里的sort函数实现还有这样的小瑕疵😐
抽空去提个issue