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

总结C++中的STL

  • 1.STL 概述

STL 即标准模板库,是 C++ 标准程序库的重要组成部分,包含常用数据结构和算法,体现了泛型化程序设计思想,基于模板实现,提高了代码的可复用性

2.容器

2.1 序列容器

  1.  vector

  • 特性:动态数组,内存连续分配。随着元素的添加,若内存空间不足,会重新分配更大的内存块,并将原有元素复制过去。
  • 优缺点:优点是支持随机访问,可通过下标快速访问任意位置的元素;在尾部插入和删除元素效率高。缺点是在中间或头部插入和删除元素效率低,因为需要移动后续元素。
  • 常用操作
  • #include <vector>
    #include <iostream>
    int main() {std::vector<int> vec;vec.push_back(10); // 尾部插入元素vec.insert(vec.begin(), 5); // 在开头插入元素std::cout << vec[1] << std::endl; // 随机访问元素vec.pop_back(); // 尾部删除元素return 0;
    }
    

    2. deque

    • 特性:双端队列,由多个固定大小的数组块组成,支持在两端快速插入和删除元素,同时也支持随机访问。
    • 优缺点:优点是在两端插入和删除元素的时间复杂度为常数,适合需要频繁在两端操作的场景。缺点是随机访问的效率略低于 vector
    • 常用操作
  • #include <deque>
    #include <iostream>
    int main() {std::deque<int> dq;dq.push_front(1); // 头部插入元素dq.push_back(2); // 尾部插入元素std::cout << dq[0] << std::endl; // 随机访问元素dq.pop_front(); // 头部删除元素return 0;
    }
    

        3. list

  • 特性:双向链表,每个节点包含数据和指向前一个节点和后一个节点的指针。
  • 优缺点:优点是在任意位置插入和删除元素的时间复杂度为常数,适合频繁插入和删除的操作。缺点是不支持随机访问,访问元素需要从头或尾开始遍历。
  • 常用操作
  • #include <list>
    #include <iostream>
    int main() {std::list<int> lst = {1, 2, 3};auto it = lst.begin();++it;lst.insert(it, 4); // 在指定位置插入元素lst.erase(it); // 删除指定位置元素for (int i : lst) {std::cout << i << " ";}return 0;
    }

2.2 关联容器

1.set

  • 特性:元素唯一且有序,底层通常实现为红黑树(一种自平衡二叉搜索树)。插入、删除和查找元素的时间复杂度为 O(logn)。
  • 优缺点:优点是元素自动排序,且能保证元素的唯一性。缺点是插入和查找操作的时间复杂度不是常数级。
  • 常用操作
#include <set>
#include <iostream>
int main() {std::set<int> s;s.insert(3);s.insert(1);auto it = s.find(1); // 查找元素if (it != s.end()) {std::cout << "Found" << std::endl;}return 0;
}

2.multiset

  • 特性:与 set 类似,但允许元素重复。
  • 常用操作:基本与 set 相同,只是插入重复元素时不会被忽略。

3.map

  • 特性:键值对的集合,键唯一且有序,底层同样是红黑树。可通过键快速查找对应的值。
  • 优缺点:优点是查找和插入操作的时间复杂度为 O(logn),且能保证键的有序性。缺点是空间开销较大。
  • 常用操作
#include <map>
#include <iostream>
#include <string>
int main() {std::map<std::string, int> m;m["apple"] = 10; // 插入键值对auto it = m.find("apple"); // 查找键if (it != m.end()) {std::cout << it->second << std::endl; // 输出对应的值}return 0;
}

4.multimap

  • 特性:与 map 类似,但允许键重复。

2.2 无序容器

   1.unordered_set

  • 特性:无序集合,元素唯一,底层实现为哈希表。插入、删除和查找元素的平均时间复杂度为 O(1)。
  • 优缺点:优点是查找和插入操作的平均时间复杂度为常数级。缺点是元素无序,且哈希冲突可能会影响性能。
  • 常用操作
#include <unordered_set>
#include <iostream>
int main() {std::unordered_set<int> us;us.insert(3);auto it = us.find(3); // 查找元素if (it != us.end()) {std::cout << "Found" << std::endl;}return 0;
}

2.unordered_multiset

  • 特性:与 unordered_set 类似,但允许元素重复。

3.unordered_map

  • 特性:无序键值对集合,底层为哈希表。适合快速查找键对应的值。
  • 常用操作
#include <unordered_map>
#include <iostream>
#include <string>
int main() {std::unordered_map<std::string, int> um;um["apple"] = 10; // 插入键值对auto it = um.find("apple"); // 查找键if (it != um.end()) {std::cout << it->second << std::endl; // 输出对应的值}return 0;
}

4.unordered_multimap

  • 特性:与 unordered_map 类似,但允许键重复。

3. 迭代器(Iterators)

3.1 输入迭代器

  • 特性:只能用于读取容器中的元素,不支持写入操作,且只能单向移动,每次移动一步。例如 find 算法使用输入迭代器来查找元素。
#include <vector>
#include <algorithm>
#include <iostream>
int main() {std::vector<int> vec = {1, 2, 3};auto it = std::find(vec.begin(), vec.end(), 2);if (it != vec.end()) {std::cout << *it << std::endl;}return 0;
}

3.2 输出迭代器

  • 特性:只能用于向容器中写入元素,不支持读取操作,同样只能单向移动,每次移动一步。例如 copy 算法使用输出迭代器将元素从一个容器复制到另一个容器。
#include <vector>
#include <algorithm>
#include <iostream>
int main() {std::vector<int> src = {1, 2, 3};std::vector<int> dest(3);std::copy(src.begin(), src.end(), dest.begin());for (int i : dest) {std::cout << i << " ";}return 0;
}

3.3 前向迭代器

  • 特性:支持读取和写入操作,并且可以向前移动,允许多次遍历容器。例如 forward_list 的迭代器就是前向迭代器。
#include <forward_list>
#include <iostream>
int main() {std::forward_list<int> fl = {1, 2, 3};for (auto it = fl.begin(); it != fl.end(); ++it) {*it *= 2; // 写入操作}for (int i : fl) {std::cout << i << " ";}return 0;
}

3.4 双向迭代器

  • 特性:支持读取、写入和双向移动,可用于双向链表等数据结构。例如 list 的迭代器就是双向迭代器。
#include <list>
#include <iostream>
int main() {std::list<int> lst = {1, 2, 3};auto it = lst.end();--it; // 反向移动std::cout << *it << std::endl;return 0;
}

3.5.随机访问迭代器

  • 特性:支持随机访问,可通过下标快速访问任意位置的元素,还支持双向移动和跳跃移动。例如 vector 的迭代器就是随机访问迭代器。
#include <vector>
#include <iostream>
int main() {std::vector<int> vec = {1, 2, 3};auto it = vec.begin() + 2; // 跳跃移动std::cout << *it << std::endl;return 0;
}

4.算法

4.1 排序算法

1.sort

  • 功能:对指定范围内的元素进行排序,默认使用升序排序。
  • 示例
#include <vector>
#include <algorithm>
#include <iostream>
int main() {std::vector<int> vec = {3, 1, 2};std::sort(vec.begin(), vec.end());for (int i : vec) {std::cout << i << " ";}return 0;
}

2.stable_sort

  • 功能:与 sort 类似,但能保证相等元素的相对顺序不变。

4.2 查找算法

1.find

  • 功能:在指定范围内查找指定值的元素,返回第一个匹配元素的迭代器。
  • 示例
#include <vector>
#include <algorithm>
#include <iostream>
int main() {std::vector<int> vec = {1, 2, 3};auto it = std::find(vec.begin(), vec.end(), 2);if (it != vec.end()) {std::cout << "Found" << std::endl;}return 0;
}

2.binary_search

  • 功能:在有序范围内进行二分查找,判断指定值是否存在。
  • 示例
#include <vector>
#include <algorithm>
#include <iostream>
int main() {std::vector<int> vec = {1, 2, 3};bool found = std::binary_search(vec.begin(), vec.end(), 2);if (found) {std::cout << "Found" << std::endl;}return 0;
}

4.3 遍历算法

1. for_each:对容器中的每个元素执行指定的函数或函数对象。

#include <vector>
#include <algorithm>
#include <iostream>
void print(int i) {std::cout << i << " ";
}
int main() {std::vector<int> vec = {1, 2, 3};std::for_each(vec.begin(), vec.end(), print);return 0;
}

2. transform:将一个容器中的元素按照指定的规则转换为另一个容器中的元素。

4.4 数值算法

1. accumulate:计算容器中元素的总和,还可以指定一个初始值,时间复杂度为 O(n)。

示例:

#include <vector>
#include <numeric>
#include <iostream>
int main() {std::vector<int> vec = {1, 2, 3};int sum = std::accumulate(vec.begin(), vec.end(), 0);std::cout << sum << std::endl;return 0;
}

2. inner_product:计算两个容器对应元素的乘积之和,可用于计算向量的内积等。

4.5.仿函数

仿函数是一个重载了函数调用运算符 () 的类或结构体。

可以像函数一样被调用,并且可以携带状态信息。

在 STL 算法中,常作为参数来定制算法的行为,例如定义比较规则、计算规则等。

1.一元仿函数

  • 示例:定义一个仿函数用于判断元素是否为偶数。
#include <vector>
#include <algorithm>
#include <iostream>
struct IsEven {bool operator()(int num) const {return num % 2 == 0;}
};
int main() {std::vector<int> vec = {1, 2, 3};auto it = std::find_if(vec.begin(), vec.end(), IsEven());if (it != vec.end()) {std::cout << *it << std::endl;}return 0;
}

2.二元仿函数

  • 示例:定义一个仿函数用于降序排序。
#include <vector>
#include <algorithm>
#include <iostream>
struct GreaterThan {bool operator()(int a, int b) const {return a > b;}
};
int main() {std::vector<int> vec = {1, 2, 3};std::sort(vec.begin(), vec.end(), GreaterThan());for (int i : vec) {std::cout << i << " ";}return 0;
}

6.适配器

6.1 容器适配器

1.stack:栈适配器,基于 deque 或 vector 实现,提供了后进先出(LIFO)的存储方式。

  • 常用操作
#include <stack>
#include <iostream>
int main() {std::stack<int> st;st.push(1);st.push(2);std::cout << st.top() << std::endl; // 访问栈顶元素st.pop(); // 弹出栈顶元素return 0;
}

2.queue:队列适配器,基于 deque 实现,提供了先进先出(FIFO)的存储方式。

  • 常用操作
#include <queue>
#include <iostream>
int main() {std::queue<int> q;q.push(1);q.push(2);std::cout << q.front() << std::endl; // 访问队首元素q.pop(); // 弹出队首元素return 0;
}

3.priority_queue:优先队列适配器,基于 vector 实现,元素按照优先级进行存储和访问。

  • 常用操作
#include <queue>
#include <iostream>
int main() {std::priority_queue<int> pq;pq.push(3);pq.push(1);std::cout << pq.top() << std::endl; // 访问队首元素pq.pop(); // 弹出队首元素return 0;
}

6.2 迭代器适配器

1.reverse_iterator:反向迭代器,用于反向遍历容器,通过将正向迭代器进行封装,实现了与正向迭代器相反的遍历顺序。

示例:

#include <vector>
#include <iostream>
int main() {std::vector<int> vec = {1, 2, 3};for (auto it = vec.rbegin(); it != vec.rend(); ++it) {std::cout << *it << " ";}return 0;
}

2.back_insert_iterator:后插入迭代器,用于在容器尾部插入元素,常用于将元素插入到一个动态增长的容器中。

6.3 仿函数适配器

1.bind:用于绑定仿函数的参数,将一个多参数的仿函数转换为一个少参数的仿函数。

示例:

#include <iostream>
#include <functional>
int add(int a, int b) {return a + b;
}
int main() {auto add5 = std::bind(add, 5, std::placeholders::_1);std::cout << add5(3) << std::endl; // 输出 8return 0;
}

2.not1not2:用于对一元和二元仿函数取反,即返回与原仿函数相反的结果。以下将更详细地介绍 C++ STL 的各个组成部分:

相关文章:

  • C++笔记-继承(下)(包含派生类的默认成员函数,菱形继承等)
  • 代码随想录单调栈part1
  • 使用CubeMX新建DMA工程——存储器到存储器模式
  • 计网_PPP协议
  • MOOS-ivp使用(一)——水下机器人系统的入门与使用
  • 【STM32单片机】#12 SPI通信(软件读写)
  • Ollama 本地运行 Qwen 3
  • 连接linux虚拟机并运行C++【从0开始】
  • 【Day 14】HarmonyOS分布式数据库实战
  • Hibernate与MybatisPlus的混用问题(Invalid bound statement (not found))
  • C++11新特性_Lambda 表达式
  • 【C++】类和对象【中下】
  • kmodel文件分析
  • 类成员函数编译链接的过程
  • 机器视觉开发-摄像头扫描二维码
  • 浅谈高校教育改革
  • 学习笔记:Qlib 量化投资平台框架 — MAIN COMPONENTS Part Ⅳ
  • 新能源行业供应链规划及集成计划报告(95页PPT)(文末有下载方式)
  • 深入理解C语言中的整形提升与算术转换
  • 【业务领域】PCIE协议理解
  • “上博号”彩绘大飞机今日启航:万米高空传播中国古代文化
  • “女乘客遭顺风车深夜丢高速服务区”续:滴滴永久封禁两名涉事司机账号
  • 游客曝九寨沟打网约车被出租车围堵,官方:前者违规,后者做法不对
  • 中行一季度净赚超543亿降2.9%,利息净收入降逾4%
  • 解读|特朗普“助攻”下加拿大自由党“惨胜”,卡尼仍需克服“特鲁多阴影”
  • 日趋活跃!2024年我国数据生产总量同比增长25%