STL源码剖析——算法

数值算法

#include <numeric>

 

accumulate

计算累积总和

第二个版本接收BinaryOperation参数取代operator+

template <class InputIterator, class T>
T accumulate<InputIterator first, InputIterator last, T init) {
    for (; first != last; ++first)
        init = init + *first;
    return init;
}

adjacent_difference

将相邻两元素的差(后-前)赋值给目的端

将*first赋值给*result, 并将其余的*i-*(i-1)值赋给*(result+(i-first))

可以作为in place运算

第二个版本接收BinaryOperation参数取代operator-

template <class InputIterator, class OutputIterator>
OutputIterator adjacent_difference(InputIterator first, InputIterator last, OutputIterator result);

inner_product

将范围内的元素作*操作,并累加

第二个版本接收2个BinaryOperation参数,分别用来取代operator+和operator*

template <class InputIterator1, class InputIterator2, class T>
T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init)

partial_sum

将*first赋值给*result, 并将其余的*i+*(i-1)值赋给*(result+(i-first))

第二个版本接收BinaryOperation版本取代operator+

template <class InputIterator, class OutputIterator>
OutputIterator partial_sum(InputIterator first, InputIterator last, OutputIterator result);

itoa

将区间填入value, value+1, value+2…

template <class ForwardIterator, class T>
void itoa(Forward first, ForwardIterator last, T value);

 

 

power

乘幂

第二个版本接收MonoidOperation取代operator*

template <class T, class Integer>
inline T power(T x, Integer n);

 

基本算法

#include <algorithm>

 

equal

判断两个区间是否相等

第二个版本提供仿函数pred取代operator=

template <class InputIterator1, class InputIterator2>
inline bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first);

fill/fill_n

fill:将区间内所有元素改为新的值

fill_n:将前n个元素改为新的值

   返回被填入的最后一个元素的下一个位置

    防止越界可以采用inserter():fill_n(inserter(iv, iv.begin()), n, value)

template <class OutputIterator, class Size, class T>

template <class ForwardIterator, class T>
void fill(ForwardIterator first, ForwardIterator last, const T& value);

template <class OutputIterator, class Size, class T>
OutputIterator fill_n(OutputIterator first, Size n, const T &value);

 

copy/copy_backward

将[first,last)拷贝到result开始的区间,返回result + (last - first)

当result位于[first, last)区间时,copy可能出错

而当输出区间尾端位于[first, last)时,copy_backward可能出错

使用memmove会将整个区间内容先复制,没有上述被覆盖的问题

 

template <class InputIterator, class OutputIterator>
inline OutputIterator copy(InputIterator first, InputIterator last,
                    OutputIterator result);

为自定义的类设置type traits,否则可能会被编译器(根据不同编译器的能力)视为non-trivial

__STL_TEMPLATE_NULL sstruct __type_traits<C> {
    typedef __false_type has_trivial_default_constructor;
    typedef __true_type has_trivial_copy_constructor;
    typedef __true_type has_trivial_assignment_operator;
    typedef __true_type has_trivial_destructor;
    typedef __false_type is_POD_type;
};
    

set相关算法

set_union

针对sorted range

构造S1和S2的并集,返回输出区间的尾端

如果某个值在S1出现n次,S2出现m次,则在输出区间会出现max(m,n)次

template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
                         InputIterator2 first2, InputIterator2 last2,
                         OutputIterator result);
                            

set_intersection

针对sorted range

构造S1和S2的交集,返回输出区间的尾端

如果某个值在S1出现n次,S2出现m次,则在输出区间会出现min(m,n)次

template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1,
                         InputIterator2 first2, InputIterator2 last2,
                         OutputIterator result);
                            

set_difference

针对sorted range

构造S1和S2的差集,返回输出区间的尾端

如果某个值在S1出现n次,S2出现m次,则在输出区间会出现min(n-m,n)次

template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
                         InputIterator2 first2, InputIterator2 last2,
                         OutputIterator result);
                            

set_symmetric_difference

针对sorted range

构造S1和S2的对称差集,(S1-S2)∪(S2-S1),返回输出区间的尾端

如果某个值在S1出现n次,S2出现m次,则在输出区间会出现min(n-m,n)次

template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_symmetric_difference(InputIterator1 first1, InputIterator1 last1,
                         InputIterator2 first2, InputIterator2 last2,
                         OutputIterator result);
                            

 

其他算法

adjacent_find

找出第一组满足条件的相邻元素,默认为相等条件

template <class ForwardIterator>
ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last);

count

计算区间内=value的元素个数

template <class InputIterator, class T>
typename iterator_traits<InputIterator>::difference_type
count(InputIterator first, InputIterator last, cont T& value);

count_if

将元素传递给仿函数pred,返回pred结果为true的元素个数

template <class InputIterator, class Predicate>
typename iterator_traits<InputIterator>::difference_type
count_if(InputIterator first, InputIterator last, Predicate pred);

find

找出第一个=value的元素

template <class InputIterator, class T>
typename iterator_traits<InputIterator>::difference_type
find(InputIterator first, InputIterator last, cont T& value);

find_if

找出第一个使pred返回true的元素

template <class InputIterator, class Predicate>
typename iterator_traits<InputIterator>::difference_type
find_if(InputIterator first, InputIterator last, Predicate pred);

find_first_of/find_end

在第一个序列查找第一次/最后一次出现序列二的位置

如果不存在,则返回last1

template <class ForwardIterator1, class ForwardIterator2>
inline ForwardIterator1
find_end(ForwardIterator1 first1, ForwardIterato1 last1,
         ForwardIterator2 first2, ForwardIterato2 last2);

template <class ForwardIterator1, class ForwardIterator2>
inline ForwardIterator1
find_first_of(ForwardIterator1 first1, ForwardIterato1 last1,
         ForwardIterator2 first2, ForwardIterato2 last2);

for_each

将反函数f实施于每一个元素

不能进行赋值

template <class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f);

generate/generate_n

将仿函数gen的运算结果填写在区间内的所有/n个元素上

template <class ForwardIterator, class Generator>
Function generate(ForwardIterator first, ForwardIterator last, Generator gen);

template <class OutputIterator, class Size, class Generator>
Function generate_n(OutputIterator first, Size n, Generator gen);

includes

判断序列2是否涵盖于序列1中

必须是有序集合,元素可以重复

includes(S1,begin(), S1.end(), S2.begin(), S2.end()); //默认递增序列
includes(S1,begin(), S1.end(), S2.begin(), S2.end(), greater<int>()); //递减序列 

//默认递增版本
template <class InputIterator1, class InputIterator2>
bool includes(InputIterator1 first1, InputIterator1 last1,
              InputIterator2 first2, InputIterator2 last2);

max_element/min_element

返回最大/最小的元素

template <class ForwardIterator>
ForwardIterator max_element(ForwardIterator first, ForwardIterator last);

template <class ForwardIterator>
ForwardIterator min_element(ForwardIterator first, ForwardIterator last);

merge

将两个有序序列合并成一个有序序列

返回最后一个元素的下一个位置

merge(S1,begin(), S1.end(), S2.begin(), S2.end()); //默认递增序列
merge(S1,begin(), S1.end(), S2.begin(), S2.end(), greater<int>()); //递减序列
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator merge(InputIterator1 first1, InputIterator1 last1,
                         InputIterator2 first2, InputIterator2 last2,
                         OutputIterator result);
                            

partition

将区间中的元素重新排列,所有被pred判定为ture的元素会被放在区间的前段

不稳定

template <class BidirectionalIterator, class Predicate>
BidirectionalIterator partition(BidirectionalIterator first,
                                BidirectionalIterator last,
                                Predicate pred);

remove/remove_copy/remove_if/remove_copy_if

移除区间中所有与value相等/满足pred=true的元素,但是不删除

返回值标出重新整理后的最后元素的下一个位置

remove在原来的容器内进行,remove_copy在另一个区间进行

template <class ForwardIterator, class T>
ForwardIterator remove(ForwardIterator first, ForwardIterator last,
                        const T& value)

template <class ForwardIterator, class OutputIterator, class T>
OutputIterator remove_copy(ForwardIterator first, ForwardIterator last,
                        OutputIterator result, const T& value)

template <class ForwardIterator, class Predicate>
ForwardIterator remove_if(ForwardIterator first, ForwardIterator last,
                        Predicate pred)

template <class ForwardIterator, class OutputIterator, class Predicate>
OutputIterator remove_copy_if(ForwardIterator first, ForwardIterator last,
                        OutputIterator result, Predicate pred)

replace/replace_copy/replace_if/replace_copy_if

将区间内所有old_value/满足pred=true的值用new_value取代

replace改变原来的容器;replace_copy不改变原来的容器,在新的容器内操作

template <class ForwardIterator, class T>
ForwardIterator replace(ForwardIterator first, ForwardIterator last,
                        const T& old_value, const T& new_value);

template <class ForwardIterator, class OutputIterator, class T>
OutputIterator replace_copy(ForwardIterator first, ForwardIterator last,
                        OutputIterator result,
                        const T& old_value, const T& new_value);

template <class ForwardIterator, class Predicate, class T>
ForwardIterator replace_if(ForwardIterator first, ForwardIterator last,
                        Predicate pred, const T& new_value);

template <class ForwardIterator, class OutputIterator, class Predicate, class T>
OutputIterator replace_copy_if(ForwardIterator first, ForwardIterator last,
                        OutputIterator result, Predicate pred, const T& new_value);

replace/replace_copy/replace_if/replace_copy_if

将区间内所有old_value/满足pred=true的值用new_value取代

replace改变原来的容器;replace_copy不改变原来的容器,在新的容器内操作

template <class BidirectionalIterator>
inline void reverse(BidirectionalIterator first, BidirectionalIterator last);

template <class BidirectionalIterator, class OutputIterator>
inline void reverse_copy(BidirectionalIterator first, 
                         BidirectionalIterator last,
                         OutputIterator result);

rotate/rotate_copy

将[first, middle]内的元素和[middle, last]内的元素互换

forward iterator

bidirectional iterator

template <class ForwardIterator>
inline void rotate(ForwardIterator first, ForwardIterator middle,
                   ForwardIterator last);

template <class ForwardIterator, class OutputIterator>
inline void rotate(ForwardIterator first, ForwardIterator middle,
                   ForwardIterator last, OutputIterator result);

search

在序列一中,查找序列二的首次出现点

不存在返回last1

允许指定某个二元运算符用来代替=的结果

template <class ForwardIterator1, class ForwardIterator2>
inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
                               ForwardIterator2 first2, ForwardIterator2 last2)

search_n

在序列中查找连续count个等于value或者符合条件的元素

允许用户提供某个二元运算用来代替=的结果

template <class ForwardIterator, class Integer, class T>
ForwardIterator search_n(ForwardIterator first, ForwardIterator last,
                         Inter count, const T& value);

swap_ranges

将区间1的元素与区间2的元素互相交换

区间1和区间2长度相同

返回区间2中的最后一个被交换元素的下一个位置

template <class ForwardIterator1, class ForwardIterator2>
ForwardIterator2 swap_range(ForwardIterator1 first1, ForwardIterator1 first1,
                            ForwardIterator2 first2);

transform

版本一:以仿函数op作用于区间中的每一个元素,并产生一个新序列

版本二:以仿函数binary_op作用于区间1和区间2的对应元素上,并产生一个新序列

template <class InputIterator, class OutputIterator, class UnaryOperator>
OutputIterator transform(InputIterator first, InputIterator last,
                         OutputIterator result, UnaryOperation op);

template <class InputIterator1, class InputIterator2,
          class OutputIterator, class BinaryOperation>
OutputIterator transform(InputIterator first1, InputIterator last1,
                         InputIterator2 first2,
                         OutputIterator result, BinaryOperation binary_op);

unique/unique_copy

将相邻的重复元素删除,返回迭代器指向新区间的尾端

unique_copy将结果复制道以result开头的区间上,返回区间尾端

提供第二个版本使用Binary Predicate判断相邻元素是否重复

unique_copy有两个版本:

1.ForwardIterator

2.OutputIterator无法进行读取,不能进行*result != *first的操作,需要额外的变量

template <class ForwardIterator>
ForwardIterator unique(ForwardIterator first, ForwardIterator last);

template <class InputIterator, class OutputIterator>
ForwardIterator unique_copy(InputIterator first, 
                            InputIterator last,
                            OutputIterator result);

lower_bound

二分查找,返回>=value的第一个元素

否则返回last

第二个版本提供仿函数comp代替<

分为forward和RandomAccess两个版本

template <class ForwardIterator, class T>
inline ForwardIterator lower_bound(ForwardIterator first,
                                   ForwardIterator last,
                                   const T& value);

upper_bound

二分查找,返回>value的第一个元素

否则返回last

第二个版本提供仿函数comp代替<

分为forward和RandomAccess两个版本

template <class ForwardIterator, class T>
inline ForwardIterator upper_bound(ForwardIterator first,
                                   ForwardIterator last,
                                   const T& value);

binary_search

二分查找是否存在value

直接调用lower_bound

第二个版本提供仿函数comp代替<

template <class ForwardIterator, class T>
bool binary_search(ForwardIterator first,
                                   ForwardIterator last,
                                   const T& value);

next_permutation/prev_permutation

获取下一个/前一个排列组合(字典序)

如果没有,返回false

版本二采用仿函数comp代替<

template <class BidirectionalIterator>
bool next_permutation(BidirectionalIterator first,
                      BidirectionalIterator last);

template <class BidirectionalIterator>
bool prev_permutation(BidirectionalIterator first,
                      BidirectionalIterator last);

 

random_shuffle

将区间的元素随机重排

版本2使用产生随机数的仿函数(传递方式by reference,拥有局部状态)

 

template <class RandomAccessIterator>
inline void random_shuffle(RandomAccessIterator first,
                           RandomAccessIterator last);

partial_sort/partial_sort_copy

接收middle迭代器

对middle-first个最小元素以递增顺序排序,置于[first, middle)内

其余元素放在[middle, last)中,不保证有特定顺序

版本二使用仿函数comp代替<

算法内部采用heapsort完成

1.对[first, middle)进行make_heap()

2.将后续元素与max-heap中最大值比较,如果小于就互换并保持max-heap状态

sort

要求RandomAccessIterator

数据量大时采用快排

快排分段通常采用Median-of-Three(首尾中的中间值)

partition时令first向尾端移动直到*first>pivot

         令last首段移动直到*last < pivot

         彼此交换,继续直到两个迭代器交错

数据量少或者局部有序时采用插入排序(<16)

如果递归层次过深(由于分割不当),会改用Heap Sort

当每个子序列都有相当程度的排序,当尚未完全排序(元素个数<16时终止排序),回到母函数进行最终的插入排序

递归层次计算:

假设n个数排序

找出2^(k) <= n 的最大值k,约为log(n)

k为递归层次限制

template <class RandomAccessIterator>
inline void sort(RandomAccessIterator first,
                 RandomAccessIterator last);

equal_range

应用于有序区间

在区间中寻找value,返回迭代器i和j分别为lower_bound和upper_bound

第二个版本采用仿函数代替operator<

template <class ForwardIterator, class T>
inline pair<ForwardIterator, ForwardIterator>
equal_range(ForwardIterator first, ForwardIterator last,
            const T& value);

 

implace_merge

将有序区间[first, middle) [middle, last)合并成单一有序序列

原先可以是递增/递减

第二个版本采用仿函数代替operator<

首先分配缓冲区,

如果缓冲区足够安置序列一:

将序列一拷贝入缓冲区执行merge

如果缓冲区足够安置序列二:

将序列二拷贝入缓冲区执行merge_backwrad

否则:

将处理长度减半,递归分割

template <class BidirectionalIterator>
inline void inplace_merge(BidirectionalIterator first,
                          BidirectionalIterator middle,
                          BidirectionalIterator last);

 

nth_element

重新排列[first, last),保证[nth, last)内的元素均>=[first, nth)的元素

保证nth迭代器所指的元素值不变

提供仿函数代替operator<操作

不断以median-of-3进行分割,如果nth迭代器在左子序列,就对左子序列进行分割,否则对右子序列进行分割

template <class RandomAccessIterator>
inline void nth_element(RandomAccessIterator first,
                        RandomAccessIterator nth,
                        RandomAccessIterator last);

mergesort

分治法进行排序

需要额外内存,效率低于快排

template <class BidriectionalIter>
void mergesort(BidirectionalIter first, BidirectionalIter last);

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值