《探索C++ set与multiset容器:深入有序唯一性集合的实现与应用》
前引:在STL的关联式容器中,
set
以其严格的元素唯一性和自动排序特性成为处理有序数据的核心工具。其底层基于红黑树(Red-Black Tree)实现,保证了O(log n)的查找、插入与删除复杂度!本文将从底层原理切入,结合关键操作源码剖析,探讨set
在去重排序、高效检索等场景的工程实践。通过对比unordered_set
与自定义排序规则,揭示其在内存效率与访问性能的平衡艺术 !
目录
【一】set 与 multiset 的介绍
【二】特点详解
(1)自动排序
(2)唯一元素
(3)高效操作
(4)不支持随机访问
(5)迭代器支持
【三】接口学习
(1)构造
(2)插入
(3)迭代器访问
(4)范围for访问
(5)find 搜索+erase 删除
(6)find 搜索 与 count搜索
(7)lower 与 upper
(8)元素个数
(9)equal_range
【一】set 与 multiset 的介绍
完整解释:
在C++标准模板库(STL)中,
set
是一种关联容器,用于存储唯一元素(本身是 key),并自动按升序排序。它基于红黑树(一种自平衡二叉搜索树)实现,提供了高效的查找、插入和删除操作。set
常用于需要快速访问和唯一性保证的场景,如去重、排序或作为字典键
set 通俗理解:
基于红黑树实现的一种容器,具有自动排序(升序)+不重复的特点
multiset 通俗理解:
基于红黑树实现的一种容器,具有自动排序(升序)特点,但
multiset
的节点允许键值重复
【二】特点详解
(1)自动排序
自动排序简而言之就是当你存入数据到 set 容器时,它会自动把它插入到合适的位置,从而实现自动排序,感觉就像《搜索二叉树+中序遍历》例如:
插入(1,、9、7、6),set 容器里面存储(1、6、7、9)
(2)唯一元素
唯一性体现在数据的独一无二,例如:
插入(1、2、3、3、3、7、7、6),set 容器里面存储(1、2、3、6、7)
(3)高效操作
查找 插入 删除:我们可以根据《搜索二叉树》理解,每次折半,那么时间复杂度可以保证在O(logn),这些高效性源于红黑树的平衡特性!
(4)不支持随机访问
它的结构不是像数组那样的下标访问,元素的位置由树结构决定
(5)迭代器支持
支持正向和反向两种迭代器(下文有例举!)
【三】接口学习
(1)构造
set 比较常使用的是默认构造:set + 数据类型 + 变量
set<int> V;
(2)插入
V.insert(9);
(3)迭代器访问
set<int>::iterator it = V.begin();
while (it != V.end())
{cout << *it << " ";it++;
}
(4)范围for访问
for (auto e : V)
{cout << e << " ";
}
(5)find 搜索+erase 删除
第一种查找:库里面通用的查找函数,属于暴力查找,时间复杂度为 O(N)
第二种查找:set 容器里面的,根据 set 的结构查找,时间复杂度为 O(logn)
//搜索+删除auto st = find(V.begin(), V.end(), 5); //第一种
auto st = V.find(8); //第二种
if (st != V.end())
{V.erase(10);
}
(6)find 搜索 与 count搜索
find:如果找到指定元素了,会返回它的位置,否则返回end
count:如果找到指定元素返回1,否则返回0
(7)lower 与 upper
lower_bound:返回范围内 >= 指定元素的位置,否则返回end
例如:(1,2,3,4,6,7,8)查找4,返回4的位置;查找5,返回6的位置
upper_bound:返回范围内 > 指定元素的位置,否则返回end
例如:(1,2,3,4,6,7,8)查找4,返回6的位置
(8)元素个数
V.size();
(9)equal_range
返回值:
该函数返回一个 pair
其成员 pair::first 是范围的下限(与 lower_bound 相同)>=
pair::second 是上限(与 upper_bound 相同)>