承德市住房和城乡建设局网站,做app需要什么软件,企业老板培训课程,网站可信图标引言
C 标准模板库#xff08;STL#xff09;提供了一组功能强大的容器类#xff0c;用于存储和操作数据集合。不同的容器具有独特的特性和应用场景#xff0c;因此选择合适的容器对于程序的性能和代码的可读性至关重要。对于刚接触 C 的开发者来说#xff0c;了解这些容…引言
C 标准模板库STL提供了一组功能强大的容器类用于存储和操作数据集合。不同的容器具有独特的特性和应用场景因此选择合适的容器对于程序的性能和代码的可读性至关重要。对于刚接触 C 的开发者来说了解这些容器的基础知识以及它们的特点是迈向高效编程的重要一步。本文将详细介绍 C 常用的容器包括序列容器std::vector、std::array、std::list、std::deque、关联容器std::set、std::map和无序容器std::unordered_set、std::unordered_map全面解析它们的特点、用法、适用场景及常见操作。 一、C 容器的分类
C 容器按照用途大致分为三大类 序列容器Sequence Containers 元素按顺序存储。支持动态调整大小和顺序访问操作。包括std::vector、std::array、std::deque、std::list。 关联容器Associative Containers 元素以键值对存储通常用于高效查找。数据存储有序底层实现为平衡二叉树如红黑树。包括std::set、std::map、std::multiset、std::multimap。 无序容器Unordered Containers 元素以哈希表存储查找性能优于关联容器但数据无序。包括std::unordered_set、std::unordered_map。 二、序列容器解析
序列容器的特点是元素按插入顺序排列适用于处理需要频繁访问或者保持顺序的数据场景。
1. std::vector
简介
std::vector 是一个动态数组支持自动扩展和随机访问适用于需要频繁随机访问的场景。它是初学者最常使用的容器之一因为它的使用方式和普通数组非常类似但多了动态管理内存的功能。
特点
动态扩展std::vector 的大小会根据需求动态调整当元素数目超过当前容量时它会自动分配更多的内存来容纳新元素。连续存储数据存储在连续的内存块中因此访问性能高遍历时效率优于链表等非连续存储容器。插入和删除效率 尾部操作高效在尾部添加或删除元素的时间复杂度是 (O(1))非常高效。中间插入或删除效率低由于 vector 是连续存储插入或删除中间元素时需移动大量元素因此效率为 (O(n))。
常用操作
操作方法描述添加元素push_back()在尾部插入元素删除尾部元素pop_back()删除尾部元素插入元素insert(iterator, value)在指定位置插入元素删除指定元素erase(iterator)删除指定位置的元素随机访问元素operator[] 或 at()随机访问指定索引处的元素获取大小size()返回当前元素数量检查是否为空empty()判断容器是否为空
示例代码
#include vector
#include iostreamint main() {std::vectorint vec {1, 2, 3};// 添加元素vec.push_back(4); // 在尾部添加元素 4// 修改元素vec[1] 20; // 修改第二个元素的值为 20// 插入和删除vec.insert(vec.begin() 2, 10); // 在索引 2 的位置插入元素 10vec.erase(vec.begin() 1); // 删除索引 1 的元素// 遍历并输出元素for (int val : vec) {std::cout val ;} // 输出 1 10 3 4return 0;
}适用场景
std::vector 适合需要频繁随机访问或尾部增删元素的场景比如处理一组动态变化的数值或管理待办事项列表等。 2. std::array
简介
std::array 是固定大小的静态数组大小在编译时确定。它的用法与普通 C 风格数组非常相似但提供了一些更安全、更便捷的操作接口。
特点
轻量高效std::array 是静态分配的因此不涉及动态内存分配这使得它非常高效。固定大小数组大小在编译时确定因此不支持动态扩展适合已知大小的数据集合。随机访问高效访问任意元素的时间复杂度为 (O(1))类似普通数组。
常用操作
操作方法描述访问元素operator[] 或 at()随机访问元素获取大小size()返回固定大小获取头尾元素front() / back()获取第一个或最后一个元素填充所有元素fill(value)用指定值填充整个数组
示例代码
#include array
#include iostreamint main() {std::arrayint, 4 arr {1, 2, 3, 4};arr[2] 10; // 修改第三个元素的值为 10// 遍历并输出元素for (int val : arr) {std::cout val ;} // 输出 1 2 10 4return 0;
}适用场景
std::array 适合用于需要固定大小且已知的数据集合比如存储 RGB 颜色值或者某个固定大小的矩阵行数据。 3. std::list
简介
std::list 是双向链表适用于频繁的中间插入和删除操作。在链表中每个元素都有一个指向前后元素的指针这使得在任何位置进行插入和删除都非常高效。
特点
高效插入和删除在链表中的插入和删除时间复杂度为 (O(1))不需要像 vector 一样移动其他元素。随机访问效率低由于链表没有连续存储不能通过索引直接访问某个元素必须从头或尾遍历因此随机访问的效率很低。
常用操作
操作方法描述添加元素push_front() / push_back()在头部或尾部添加元素删除元素pop_front() / pop_back()删除头部或尾部元素插入元素insert(iterator, value)在指定位置插入元素删除指定元素erase(iterator)删除指定位置的元素
示例代码
#include list
#include iostreamint main() {std::listint lst {1, 2, 3};lst.push_back(4); // 在尾部添加元素 4lst.insert(std::next(lst.begin(), 1), 10); // 在第二个位置插入元素 10lst.pop_front(); // 删除头部元素// 遍历并输出元素for (int val : lst) {std::cout val ;} // 输出 10 2 3 4return 0;
}适用场景
std::list 适合频繁的中间插入和删除尤其是当数据集合较大并且需要灵活调整时比如管理网络节点或实现复杂的缓存算法。 4. std::deque
简介
std::deque 是双端队列支持在头部和尾部快速插入和删除。它可以理解为 vector 和 list 的结合具有两者的优点。
特点
高效双端操作无论是头部还是尾部插入/删除时间复杂度均为 (O(1))。支持随机访问与 vector 类似deque 支持通过索引直接访问元素但它的底层存储结构并非一个连续的内存块。
常用操作
操作方法描述添加元素push_front() / push_back()在头部或尾部添加元素删除元素pop_front() / pop_back()删除头部或尾部元素随机访问元素operator[] 或 at()随机访问元素
示例代码
#include deque
#include iostreamint main() {std::dequeint dq {1, 2, 3};dq.push_front(0); // 在头部添加元素 0dq.push_back(4); // 在尾部添加元素 4// 遍历并输出元素for (int val : dq) {std::cout val ;} // 输出 0 1 2 3 4return 0;
}适用场景
std::deque 适合在头尾都需要频繁增删数据的场景比如模拟队列或双向缓存。 三、关联容器解析
关联容器用于存储键值对通常用于高效查找、插入和删除操作。
1. std::set
简介
std::set 是集合容器用于存储不重复的元素底层实现为红黑树具有自动排序的功能。
特点
有序存储元素按照升序排列保证数据有序。查找高效set 使用平衡二叉树查找、插入和删除的时间复杂度为 (O(\log n))。唯一性set 保证集合中不会有重复的元素。
常用操作
操作方法描述添加元素insert(value)插入一个元素删除元素erase(iterator)删除指定元素查找元素find(value)查找元素是否存在
示例代码
#include set
#include iostreamint main() {std::setint s {3, 1, 4};s.insert(2); // 插入元素 2s.erase(1); // 删除元素 1// 遍历并输出元素for (int val : s) {std::cout val ;} // 输出 2 3 4return 0;
}适用场景
std::set 适合需要保证数据唯一性并且需要有序存储的场景比如保存用户 ID、追踪唯一的值等。 2. std::map
简介
std::map 是键值对容器类似于字典它也是通过红黑树实现的因此提供了有序的数据存储方式。
特点
有序存储键值对按照键的顺序存储。查找高效map 的查找、插入和删除操作的时间复杂度为 (O(\log n))。键唯一每个键都是唯一的。
常用操作
操作方法描述添加元素operator[] 或 insert()添加或更新键值对删除元素erase(iterator)删除指定键的元素查找元素find(key)查找指定键是否存在
示例代码
#include map
#include iostreamint main() {std::mapint, std::string m {{1, one}, {2, two}};m[3] three; // 插入键值对 (3, three)// 遍历并输出键值对for (auto [key, value] : m) {std::cout key : value std::endl;}return 0;
}适用场景
std::map 适合需要快速查找键值对的场景比如存储用户信息或用于配置文件读取等。 总结容器的选择指南
场景推荐容器随机访问std::vector数据大小固定且已知std::array频繁插入和删除std::list 或 std::deque有序存储和查找std::set 或 std::map无序存储和查找std::unordered_set / std::unordered_map
通过掌握这些容器的特性和用法你将能够在开发中游刃有余地选择最佳的容器为程序带来性能和代码可读性的提升。对于刚开始学习 C 的萌新们理解这些容器的基本特性和适用场景是提高编程技能的重要一步希望这篇文章对你理解和使用 C 容器有所帮助。