STL源码剖析:算法
2020-12-13 15:09
标签:loop isp 数据 函数 迭代器 兴趣 operator 剖析 sort 算法,问题之解法也 算法好坏的衡量标准:时间和空间,单位是对数、一次、二次、三次等 算法中处理的数据,输入方式都是左闭又开,类型就迭代器, 如:[first, last) STL中提供了很多算法,我们只研究感兴趣的几种 拷贝[first, last)到[result, reslut+(last - first)) 总体考虑:对象能够直接在内存级别拷贝,还是需要单独拷贝 设计技巧:重载和特化 如下图所示:
copy_back和copy的设计方式基本相同,问题的区别是拷贝的方向不同,copy是从first开始到last拷贝,copy_back是从last开始到first拷贝 copy_back的拷贝过程: 在[first, last)中找出第一个匹配的数据,返回指向该数据的Iterator 插入排序 优点:对于小型,基本有序的数据进行排序,效率最高 缺点:对于大型数据,完全无序,效率非常低 堆排序 优点:对大型数据表现良好,所需的额外存储空间是和数据等同的大小 缺点:对于小型数据不合适 复杂度:平均O(NlogN),最坏O(N^2) 快速排序 优点:对于大型数据表现良好 缺点:递归调用耗资源,不适用于小型数据 复杂度:平均O(NlogN),最坏O(NlogN) STL中的排序算法 如果数据个数大于16,使用快速排序,如果快速排序递归的层次超过一定阈值,使用堆排序 如果数据小于16,直接使用插入排序 原因: 小数据直接使用插入排序,效率高 大型数据一开始就使用堆排序,复杂度是O(NlogN),一开始使用快速排序效率低于O(NlogN),如果一直使用快速排序,算法的复杂度会降低到最坏O(N^2),所以先快速排序再堆排序 插入排序算法源码 堆排序算法源码 见序列式容器中的堆章节 STL中的排序算法源码 STL源码剖析:算法 标签:loop isp 数据 函数 迭代器 兴趣 operator 剖析 sort 原文地址:https://www.cnblogs.com/chusiyong/p/11574252.html启
copy函数
templateclass InputIterator, class OutputIterator>
inline OutputIterator copy(InputIterator first, InputIterator last, OutputIterator reslut)
{
return __copy_dispatch
templateclass InputIterator, class OutputIterator>
struct __copy_dispatch
{
OutputIterator operator()(InputIterator first, InputIterator last, OutputIterator reslut)
{
return __copy(first, last, result, iterator_category(first));
}
}
// 特化
template class T>
struct __copy_dispatch
templateclass InputIterator, class OutputIterator>
inline OutputIterator __copy(InputIterator first, InputIterator last, OutputIterator reslut, input_iterator_tag)
{
// 以判断迭代器是否相同为标准,速度慢
for(; first != last; ++result, ++first)
{
*result = *first;
}
return result;
}
templateclass InputIterator, class OutputIterator>
inline OutputIterator __copy(InputIterator first, InputIterator last, OutputIterator reslut, random_access_iterator_tag)
{
// 完全是为了复用
return __copy_d(first, last, result, distance_type(first));
}
templateclass InputIterator, class OutputIterator, class Distance>
inline OutputIterator __copy_d(InputIterator first, InputIterator last, OutputIterator reslut, Distance*)
{
// 以判断n值是否大于0为标准,速度快
for(Distance n = last - first; n > 0; --n, ++result, ++first)
{
*result = *first;
}
return result;
}
templat class T>
inline T* __copy_t(const T* first, const T* last, T* result, __true_type)
{
// 直接复制内存
memmove(result, first, sizeof(T) * (last - first));
return result + (last - first);
}
templat class T>
inline T* __copy_t(const T* first, const T* last, T* result, __true_type)
{
// 每个数据单独复制
return __copy_d(first, last, result, (ptrdiff_t*)0);
}
copy_back函数
*(result - 1) = *(last - 1), *(result - 2) = *(last - 2)...
find函数
template class InputIterator, class T>
InputIterator find(InputIterator first, InputIterator last, const T& value)
{
while(first != last && *first != *last) ++first;
return first;
}
sort函数
template class RandomAccessIterator>
void __insert_sort(RandomAccessIterator first, RandomAccessIterator last)
{
if(first == last)
{
return;
}
for(RandomAccessIterator i = first + 1; i != last,; i++)
{
__linear_insert(first, i, value_type(first));
}
}
template class RandomAccessIterator, class T>
inline void __linear_insert(RandomAccessIterator first, RandomAccessIterator last, T*)
{
T value = *last;
if(value first)
{
// 需要插入的值比头部的值还小,直接整体拷贝
copy_back(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)
{
--next;
while(value next)
{
*last = *next;
last = next;
--next;
}
*last = value;
}
// 取三值中点
template class T>
inline const T& _median(const T& a, const T& b, const T& c)
{
if(a b)
{
if(b c)
{
return b;
}
else if(a c)
{
return c;
}
else
{
return a;
}
}
else if(a c)
{
return a;
}
else if(b c)
{
return c;
}
else
{
return b;
}
}
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;
}
}
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)
}
}
// 找出2^k
templat class Size>
inline Size __lg(Size n)
{
Size k;
for(k = 0; n > 1; n >> 1)
{
++k;
}
return k;
}
template class RandomAccessIterator, class T, class Size>
void __introsort_loop(RandomAccessIterator first, RandomAccessIterator last, T*, Size depth_limit)
{
while(last - first > 16)
{
if(depth_limit == 0)
{
partial_sort(first, last, last); // 堆排序
return;
}
--depth_limit;
// 取中值
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);
// 左半段在while中递归sort
last = cut;
}
}
template class RandomAccessIterator>
void __final_insertion_sort(RandomAccessIterator first, RandomAccessIterator last)
{
if(last - first > 16)
{
// 以下写法感觉有点冗余。先排序前16个数据,然后将后需要数据依次插入排序
__insertion_sort(first, first + 16);
__unguarded_insertion_sort(first + 16, last);
}
else
{
// 小于16,直接插入排序
__insert_sort(first, last);
}
}
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));
}
}