当前位置: 首页 > news >正文

C++ STL基础

文章目录

    • STL简介
    • STL容器
      • 顺序容器
      • 有序关联容器
      • 无序关联容器
      • 容器适配器
      • 拟容器
      • 标准容器操作复杂性
    • STL算法
      • 算法复杂性
      • 不修改序列的算法
      • 修改序列的算法
      • 排序和搜索
      • 最大/最小值
    • 参考

本文将对C++的STL进行一些基础介绍。

STL简介

STL(Standard Template Library,标准模板库),顾名思义是一堆C++模板及其支持工具所组成的库,由于STL基本占据了C++标准库的绝大部分内容,所以有时也用STL指代C++标准库。

STL开源实现:

  • https://github.com/microsoft/STL.git
  • https://sgistl.github.io/download.html
  • https://libcxx.llvm.org/
  • https://gcc.gnu.org/onlinedocs/libstdc++/
  • https://sourceforge.net/projects/stlport/

STL主要包含6大组件:

  1. 容器(containers):各种数据结构,是一种class template
  2. 算法(algorithms):各种常用算法,是一种function template
  3. 迭代器(iterators):连接容器和算法,是所谓的“泛型指针”
  4. 仿函数(functors):行为类似函数,可作为算法的某种策略。从实现角度看,仿函数是一种重载了operator()的class或者class template,一般的函数指针可以视为狭义的仿函数。
  5. 适配器(adapters):一种用来修饰容器或者仿函数或者迭代器接口的东西。
  6. 配置器(allocators):复制空间配置和管理。从实现角度看,配置器是一个实现了动态空间配置、空间管理、空间释放的class template。
    这6大组件之间的关系如下:
    在这里插入图片描述
  • 容器作为STL的主体,是许多不同的数据结构
  • 分配器为容器的实现分配应有的空间
  • 泛型算法用来处理容器中的数据
  • 迭代器是泛型算法和容器之间的粘合剂
  • 仿函数使得算法可以有更加灵活的自定义模式
  • 适配器保证了自定义的功能可以和STL中现有的功能相融合

STL容器

顺序容器

A是分配器选项,默认值为std::allocator<T>

vector<T,A>:空间连续分配的T 类型元素序列;默认选择容器
List<T,A>:T类型元素双向链表;当需要插入/删除元素当不移动已有元素时选择
forward_list<T,A>:T类型元素单向链表;很短的或空序列的理想选择
deque<T,A>:T类型元素双端队列;向量和链表的混合;对大多数应用而言,都比向量和链表要慢

有序关联容器

C是比较类型,A是分配器选项

map<K,V,C,A>:从K到V的有序映射;一个(k,V)对序列
multimap<K,V,C,A>:从K到V的有序映射;允许重复关键字
set<K,C,A>:K的有序集合
multiset<K,C,A>:K的有序集合;允许重复关键字

这些容器通常用平衡二叉树(通常是红黑树)实现,关键字K的默认序标准是std::less<K>,对映射,A的默认值为std::allocator<std::pair<const K, T>>,对集合A的默认值为std::allocator<K>

无序关联容器

H是哈希函数类型,E是相等性测试,A是分配器类型

unordered_map<K,V,H,E,A>:从K到V的无序映射
unordered_multimap<K,V,H,E,A>:从K到V的无序映射;允许重复关键字
unordered_set<K,H,E,A>:K的无序集合
unordered_multiset<K,H,E,A>:K的无序集合;允许重复关键字

这些容器都是采用一处链表法的哈希表实现。关键字类型K的默认哈希哈树类型H为std::hash<K>。关键字类型K的默认相等性判定函数类型E为std::equal_to<K>;相等性判断函数用来判断哈希值相同的两个对象是否相等。

容器适配器

C是一个容器类型

priority_queue<T,C,Cmp>:T的优先队列;Cmp是优先级函数类型
queue<T,C>:T的队列,支持push和pop操作
stack<T,C>:T的栈,支持push和pop操作

priority_queue的默认优先级函数Cmp是std::less<T>,它的底层是容器加heap。queue的默认容器类型C为std::deque<T>,stack和priority_queue的默认容器类型C为std::vector<T>

容器适配器(container adaptor)为容器提供不同(通常受限)的接口。容器适配器的实际用法就是仅通过其特殊接口使用。STL容器适配器不提供直接访问其底层容器的方式,也不提供迭代器或下标操作

拟容器

某些数据类型具有标准容器所应有的大部分特性,但有非全部,称这些容器为拟容器。

T[N]:固定大小的内置数组;没有size()或其他成员函数
array<T,N>:固定大小的数组;类似内置数组,但解决了大部分问题
basic_string<C,Tr,A>:一个连续分配空间的类型为C的字符序列,支持文本处理操作;A是分配器,Tr是字符萃取。basic_string通常经过优化,短字符串无须使用自由存储空间。
stringbasic_string<char>
u16stringbasic_string<char16_t>
u32stringbasic_string<char32_t>
wstringbasic_string<wchar_t>
valarray<T>:数值向量,支持向量运算
bitset<N>:N个二进制位的集合,支持集合操作,如&|
vector<bool>vector<T>的特化版本,紧凑保存二进制位

标准容器操作复杂性

容器下标访问任意位置插入和删除在头部插入和删除在尾部插入和删除支持迭代器
vector常量O(n)+常量+随机
list常量常量常量双向
forward_list常量常量前向
deque常量O(n)常量常量随机
stack常量
queue常量常量
priority_queueO(log(n))O(log(n))
mapO(log(n))O(log(n))+双向
multimapO(log(n))+双向
setO(log(n))+双向
multisetO(log(n))+双向
unordered_map常量+常量+前向
unordered_multimap常量+前向
unordered_set常量+前向
unordered_multiset常量+前向
string常量O(n)+O(n)+常量+随机
array常量随机
内置数组常量随机
valarray常量随机
bitset常量

STL算法

标准库算法的目标是为可有化实现的某些东西提供最通用最灵活的接口。
无论一个STL算法返回什么,它都不会是实参的容器。传递给STL算法的实参是迭代器,算法完全不了解迭代器所指向的数据结构。迭代器存在主要是为了将算法从它所处理的数据结构上分离开来。
每个算法基本都有一个使用后缀_if的版本,该版本接受一个谓词,可以指定策略。

算法复杂性

大多数算法都是线性时间O(n)的,n通常是输入序列长度。

复杂度算法
O(1)swap(), iter_swap()
O(log(n))lower_bound(), upper_bound(), equal_range(),binary_search(),push_heap(),pop_heap()
O(n*log(n))inplace_merge()(最坏情况),stable_partition(最坏情况),sort(),stable_sort(),partial_sort(),partial_sort_copy(),sort_heap()
O(n*n)find_end(),find_first_of(),search(), search_n()
O(n)所有其他算法

不修改序列的算法

  • for_each()
    f=for_each(b,e,f):对[b,e)中的每个x执行f(x)

  • 序列谓词
    all_of(b,e,f):[b,e)中所有元素x都满足f(x)吗?
    any_of(b,e,f):[b,e)中有元素x满足f(x)吗?
    none_of(b,e,f):[b,e)中所有元素x都不满足f(x)吗?

  • count()/count_if():寻找满足条件的元素数目

  • find/find_if/find_if_not/find_first_of/adjacent_find/find_end:顺序搜索具有特定值或令谓词为真的元素

  • equal/mismatch:比较一对序列

  • search/search_n:查找给定序列是否是另一个序列的子序列

修改序列的算法

修改序列的算法(可变序列算法,mutating sequence algorithm)可以修改其实参序列的元素。

  • transform
  • copy/copy_if/copy_n/copy_backward/move/move_backward:copy算法的目标序列不一定是一个容器,任何可用一个输出迭代器描述的东西都可以作为它的目标。
  • unique/unique_copy:从序列中删除连续的重复元素。
  • remove和replace
    • remove/remove_if/remove_copy./remove_copy_if:“删除”序列末尾元素
    • reverse/reverse_copy:逆序排列和拷贝
    • replace/replace_if/replace_copy/replace_copy_if
    • 这些算法不能改变输入序列的大小,即使是remove也会保持输入序列大小不变。类似unique,它是通过将元素移动到左侧来实现“删除”的。
  • rotate/retate_copy/random_shuffle/shuffle/partition/statble_partition/partition_copy/partition_point/is_partitioned:提供了移动序列中元素的系统方法,用swap来移动元素的。
  • 排列:提供了生成一方额序列所有排列的系统方法
    • next_permutation/prev_permutation/is_permutation
  • fill:fill系列算法提供了向序列元素赋值和初始化元素的方法
    • fill/fill_n/generate/generate_n/uninitialized_fill/uninitialized_fill_n/uninitialized_copy/uninitialized_copy_n
    • fill算法反复用指定值进行赋值,generate算法通过反复调用其函数实参得到的值进行赋值
    • 如果希望初始化,使用uinitialized_的版本。
  • swap/swap_ranges/iter_swap:交换对象的值,它是标准库中最简单也最重要的算法之一

排序和搜索

  • sort系列算法
    sort算法要求随机访问迭代器,排序list时一般将list元素拷贝到vector中,排序这个vector后再将元素拷回list。
  • binary_search:二分搜索算法提供了有序序列上的二分搜索,二分搜索算法不需要随机访问迭代器,一个前向迭代器就够了
    • lower_bound/upper_bound/binary_search/qual_range
  • merge:将两个有序序列合并为1个
    • merge/inplace_merge
  • 集合算法:集合算法将序列当作一个元素集合来处理,并提供基本的集合操作。输入数列应该是排好序的,输出序列也会被排序。
    • includes/set_union/set_intersection/set_difference/set_symmetric_difference
  • 堆:堆是一种按最大值优先的方式组织元素的紧凑型数据结构。可以理解为一种二叉树的表示方式。堆算法允许程序员将一个随机访问序列作为堆处理。
    • make_heap/push_heap/pop_heap/sort_heap/is_heap/is_heap_until
  • lexicographical_compare:字典序比较就是我们用来排序字典中单词的规则。

最大/最小值

  • min
  • max
  • minmax
  • min_element
  • max_element
  • minmax_element

参考

STL源码剖析

相关文章:

  • 1287. 有序数组中出现次数超过25%的元素
  • JavaScript 中的数组详解
  • 量子计算的基本运算:Hadamard 门、CNOT 门、Pauli 门详解
  • 使用excel中的VBA合并多个excel文件
  • 【Java学习】多态
  • LeetCode 501.二叉搜索树中的众数
  • C++ 移动语义
  • 电商API安全防护:JWT令牌与XSS防御实战
  • Java EE初阶-计算机导论
  • 15增减字符串匹配(贪心)思路解析+源码
  • 分布式 IO 模块:造纸设备的降本增效利器
  • 算法专题(四):前缀和
  • 累加器(Accumulators)在Spark中的应用
  • 收到线上服务器出现cpu告警一般怎么排查?
  • pytorch基础
  • 如何保证bug在改完之后不会引起新bug
  • 读书笔记-高性能mysql(理解mysql知识点)
  • 【CS285】听说过“欧氏距离”,这个“马氏距离(Mahalanobis distance)”又是什么呀?
  • Redis复制性能优化利器:深入解析replica-lazy-flush参数
  • 深入解析内存池设计:从原理到手动实现
  • 关于企业网站建设的必要性/优化大师在哪里
  • 南阳淅川县制作网站的公司/沈阳百度seo关键词优化排名
  • 网站跳转怎么做360/友情链接怎么连
  • 上海市建设协会考试网站/推广链接点击器网页
  • 什么网站做批发零食的很多/一站式营销推广
  • 网站建站公司排名/外贸seo站