zoukankan      html  css  js  c++  java
  • C++ 之 标准模板库的七大算法

    标准模板库的算法

    STL中的算法大致可以分为以下七类:

    • 不变序列算法
    • 变值算法
    • 删除算法
    • 变序算法
    • 排序算法
    • 有序区间算法
    • 数值算法

    特性 :

    • 算法就是一个个函数模板,大多数在<algorithm>中定义
    • STL中提供能在各种容器中通用的算法,比如查找,排序等
    • 算法通过迭代器来操纵容器中的元素。许多算法可以对容器中的一个局部区间进行操作,因此需要两个参数,一个是起始元素的选代器,一个是终止元素的后面一个元素的迭代器。比如,排序和查找
    • 有的算法返回一个迭代器。比如find()算法,在容器中查找一个元素,并返回一个指向该元素的迭代器
    • 算法可以处理容器,也可以处理普通数组

    不变序列算法

    • 该类算法不会修改算法所作用的容器或对象
    • 适用于顺序容器和关联容器
    • 时间复杂度都是O(n)
    算法 作用
    min 求两个对象中较小的(可自定义比较器)
    max 求两个对象中较大的(可自定义比较器)
    min_element 求区间中的最小值(可自定义比较器)
    max_element 求区间中的最大值(可自定义比较器)
    for_each 对区间中的每个元素都做某种操作
    count 计算区间中等于某值的元素个数
    count_if 计算区间中符合某种条件的元素个数
    find 在区间中查找等于某值的元素
    find_if 在区间中查找符合某条件的元素
    find_end 在区间中查找另一个区间最后一次出现的位置(可自定义比较器)
    find_first_of 在区间中查找第一个出现在另一个区间中的元素(可自定义比较器)
    adjacent_find 在区间中寻找第一次出现连续两个相等元素 的位置(可自定义比较器)
    search 在区间中查找另一个区间第一次出现的位置(可自定义比较器)
    search_n 在区间中查找第一次出现等于某值的连续n个元素(可自定义比较器)
    equal 判断两区间是否相等(可自定义比较器)
    mismatch 逐个比较两个区间的元素,返回第一次发生不相等的两个元素的位置(可自定义比较器)
    lexicographical_compare 按字典序比较两个区间的大小(可自定义比较器)

    算法示例 : find()

    template<class Inlt,class T>
    Inlt find(Inlt first,Inlt last,const T& val);
    
    • first和last 这两个参数都是容器的迭代器,它们给出了容器中的查找区间起点和终点[first,last)。区间的起点是位于查找范围之中的,而终点不是。find在[first,last)查找等于val的元素
    • 用==运算符判断相等
    • 函数返回值是一个迭代器。如果找到,则该选代器指向被找到的元素。
    • 如果找不到,则该迭代器等于last

    Example:

    p=find(v.begin),v.end(),3);
    if(!p=v.end())
        cout<<*p<<endl; 
    

    STL中"大""小"的概念

    • 关联容器内部的元素是从小到大排序的
    • 有些算法要求其操作的区间是从小到大排序的,称为"有序区间算法"
      例:binary_search 二分法/折半查找
    • 有些算法会对区间进行从小到大排序,称为"排序算法"
      例:sort
    • 还有一些其他算法会用到"大","小"的概念使用STL时,在缺省的情况下,以下三个说法等价:
      1. x 比 y 小
      2. 表达式"x<y"为真
      3. y 比 x 大

    变值算法

    • 此类算法会修改源区间或目标区间元素的值
    • 值被修改的那个区间,不可以是属于关联容器的
    算法 作用
    for_each 对区间中的每个元素都做某种操作
    copy 复制一个区间到别处
    copy_backward 复制一个区间到别处,但目标区前是从后往前被修改的
    transform 将一个区间的元素变形后拷贝到另一个区间
    swap_ranges 交换两个区间内容
    fill 用某个值填充区间
    fill_n 用某个值替换区间中的n个元素
    generate 用某个操作的结果填充区间
    generate_n 用某个操作的结果替换区间中的n个元素
    replace 将区间中的某个值替换为另一个值
    replace_if 将区间中符合某种条件的值替换成另一个值

    删除算法

    • 删除一个容器里的某些元素
    • 删除--不会使容器里的元素减少
      • 将所有应该被删除的元素看做空位子
      • 用留下的元素从后往前移,依次去填空位子
      • 元素往前移后,它原来的位置也就算是空位子
      • 也应由后面的留下的元素来填上
      • 最后,没有被填上的空位子,维持其原来的值不变删除算法不应作用于关联容器
    • 删除算法不应作用于关联容器
    • 算法复杂度都是O(n)的
    算法 作用
    remove 删除区间中等于某个值的元素
    remove_if 删除区间中满足某种条件的元素
    remove_copy 拷贝区间到另一个区间,等于某个值的元素不拷贝
    remove_copy_if 拷贝区间到另一个区间,符合某种条件的元素不拷贝
    unique 删除区间中连续相等的元素,只留下一个(可自定义比较器)
    unique_copy 拷贝区间到另一个区间.连续相等的元素,只拷贝第一个到目标区间(可自定义比较器)

    变序算法

    • 变序算法改变容器中元素的顺序
    • 但是不改变元素的值
    • 变序算法不适用于关联容器
    • 算法复杂度都是O(n)的
    算法 作用
    reverse 颠倒区间的前后次序
    reverse_Copy 把一个区间颠倒后的结果拷贝到另一个区间,源区间不变
    rotate 将区间进行循环左移
    rotate_copy 将区间以首尾相接的形式进行旋转后的结果拷贝到另一个区间,源区间不变
    next_permutation 将区间改为下一个排列(可自定义比较器)
    prev_permutation 将区间改为上一个排列(可自定义比较器)
    random_shuffle 随机打乱区间内元素的顺序
    partition 把区间内满足某个条件的元素移到前面,不满足该条件的移到后面

    排序算法

    • 比前面的变序算法复杂度更高,一般是O(nlog(n))
    • 排序算法需要随机访问迭代器的支持不适用于关联容器和list
    算法 作用
    sort 将区间从小到大排序(可自定义比较器)将区间从小到大排序
    stable_sort 并保持相等元素间的相对次序(可自定义比较器)
    partial_sort 对区间部分排序,直到最小的n个元素就位(可自定义比较器)
    partial_sort_copy 将区间前n个元素的排序结果拷贝到别处,源区间不变(可自定义比较器)
    nth_element 对区间部分排序,使得第n小的元素(n从0开始算)就位,而且比它小的都在它前面,比它大的都在它后面(可自定义比较器)

    排序算法 复杂度分析

    sort

    • 实际上是快速排序,时间复杂度O(n*log(n))
    • 平均性能最优
    • 但是最坏的情况下,性能可能非常差,如果要保证"最坏情况下"的性能,那么可以使用stable_sort

    stable_sort

    • 实际上是归并排序,特点是能保持相等元素之间的先后次序
    • 在有足够存储空间的情况下,复杂度为nlog(n),否则复杂度为nlog(n)*log(n)
    • stable_sort用法和sort相同.
    • 排序算法要求随机存取迭代器的支持,所以ist不能使用

    有序区间算法

    • 要求所操作的区间是已经从小到大排好序的
    • 需要随机访问迭代器的支持
    • 有序区间算法不能用于关联容器和list
    算法 作用
    binary_search 判断区间中是否包含某个元素 O(log(n))
    includes 判断是否一个区间中的每个元素,都在另一个区间中
    lower_bound 查找最后一个不小于某值的元素的位置
    upper_bound 查找第一个大于某值的元素的位置
    equal_range 同时获取lower_bound和upper_bound
    merge 合并两个有序区间到第三个区间人
    set_union 将两个有序区间的并拷贝到第三个区间
    set_intersection 将两个有序区间的交拷贝到第三个区间
    set difference 将两个有序区间的差拷贝到第三个区间
    set_symmetric_difference 将两个有序区间的对称差拷贝到第三个区间
    inplace_merge 将两个连续的有序区间原地合并为一个有序区间
    任世事无常,勿忘初心
  • 相关阅读:
    2015 Multi-University Training Contest 2 1004 Delicious Apples(DP)
    开门人和关门人
    数据降维 实例
    Leetcode题解(5):L58/Length of Last Word
    JavaWeb开发环境搭建
    Linux配置hugepage
    lua的函数初识
    有人离职时经理的反应是?
    svn如何回滚到之前版本
    python用httplib模块发送get和post请求
  • 原文地址:https://www.cnblogs.com/FlameBlog/p/14715302.html
Copyright © 2011-2022 走看看