关联容器的基本操作简单总结

本文详细介绍了C++ STL中的set与map容器的操作方法,包括构建、插入、大小、查找、判空与清空、删除及遍历等功能,并解释了它们内部采用红黑树实现的原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++ STL中标准关联容器set, multiset, map, multimap内部采用的就是一种非常高效的平衡检索二叉树:红黑树,也成为RB树(Red-Black Tree)。RB树的统计性能要好于一般平衡二叉树,所以被STL选择作为了关联容器的内部结构。
这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的,后边我们会见识到有序的好处。
set&multiset
一,构建
  1. set<int>s_val;  
二,插入
  1. s_val.insert(val);返回值:pair<set<int>::iterator,bool>;bool标志是否成功,前一个表示插入位置。若里面已经有此元素,则返回原元素的位置。  
三,大小
s_val.size();元素的个数。
四,查找
  1. count(val): 返回容器中值等于val的元素数目。  
  2. find(val): 返回容器中值等于val的第一个元素的iterator位置;如果没有匹配元素,则返回end()位置。  
  3. lower_bound(val): 返回容器中第一个值大于或等于val的元素的iterator位置。  
  4. upper_bound(val): 返回容器中第一个值大于val的元素的iterator位置。  
  5. equal_range(val): 返回容器中值等于val的所有元素的范围[beg, end)组成的pair<beg, end>   
五,判空&清空
  1. s_val.clear()清空  
  2. s_val.empty()判空  
六,删除
  1. s_val.erase(val):删除容器中所有值为val的元素,返回删除元素的数目  
  2. s_val.erase(pos):删除位置为pos的元素。没有返回值。  
  3. s_val.erase(begin,end):删除范围内的所有元素。  
七,遍历
  1. set<int>::iterator iter;  
  2. iter=s_val.begin()第一个元素。  
  3. s_val.end()最后一个元素的下一个元素,  
  4. set<int>::reverse_iterator riterl;  
  5. riter=s_val.rbegin();最后一个元素。  
  6. s_val.rend(); 第一个元素的前一个元素。  

map&&multimap
一,map构造方法:
  1. map<int,string>map_ins;  
二,map的插入:
  1. 1,insert()返回值:pair<set<int>::iterator,bool>;bool标志是否成功,前一个表示插入位置。若里面已经有此元素,则返回原元素的位置。  
  2. pair<int,string>p(v1,v2);  
  3. map_ins.insert(p);  
  4. while()  
  5. {  
  6. map_ins.insert(make_pair(v1,v2));  
  7. }  
  8. 2,map_ins.inser(map<int,string>::value_type(v1,v2))  
  9. 3,map_ins[1]="fdaslj";  
三,map的大小
  1. int nsize=map_ins.size();  
四,数据的查找
  1. 1,用count函数来判定关键字是否出现,其缺点是无法定位数据位置,只有0和1  
  2. 2,用find(第一个val)函数,如果有要找的数据则返回其元素的位置,否则返回end。  
  3. 3,lower_bound(val),第一个返回容器中第一个key值大于或者小于val的元素的位置  
  4.    upper_bound(val)返回第一个key值大于val的元素的iterator的位置  
  5. 4,equel_range(val):返回容器中等于val的所有元素的范围[beg, end)组成的pair<beg, end>;  
五,数据的清空和判空;
  1. clear()清空,empty()判空。  
六,数据的删除
  1. map_ins.erase(val):删除容器中所有key值为val的元素,成功返回删除元素的数目,否则0;  
  2. map_ins.erase(pos):删除位置为pos的元素。没有返回值。  
  3. map_ins.erase(begin,end):删除范围内的所有元素。  
七,数据的遍历
  1. map<int,string>::interator iter;  
  2. for(iter=map_ins.begin();iter!=map_ins.end();iter++)  
  3.   iter->second;  
  4. 或者从后往前:  
  5. map<int,string>::reverse_interator riter;  
  6. rter.rbegin,容器中的最后一个元素。  
  7. rter.end,容器中的第一个元素的前一个元素。 

C++中的无序关联容器(如 `std::unordered_map`、`std::unordered_multimap`、`std::unordered_set` 和 `std::unordered_multiset`)的底层数据结构基于**哈希表(hash table)**实现。这种数据结构通过哈希函数将键(key)映射到存储桶(buckets),每个存储桶可以包含一个或多个键-值对[^4]。 ### 哈希表的基本特性 1. **哈希函数**:无序关联容器使用哈希函数将键转换为整数,进而确定该键应被存储在哪个存储桶中。标准库提供了针对基本类型的默认哈希函数(例如 `std::hash<int>`、`std::hash<std::string>` 等),同时也允许用户自定义哈希函数。 2. **存储桶(Buckets)**:哈希表由多个存储桶组成,每个存储桶通常以链表的形式保存冲突的键-值对。当不同的键经过哈希函数后得到相同的存储桶索引时,它们会被存储在同一个链表中。 3. **负载因子(Load Factor)**:负载因子是衡量哈希表性能的重要指标,其定义为哈希表中元素总数与存储桶数量的比值。高负载因子可能导致更多的哈希冲突,从而影响性能。可以通过调整最大负载因子来控制哈希表的重新散列(rehashing)行为。 ### 时间复杂度分析 - **平均情况**:在理想情况下,哈希表的插入、删除和查找操作的时间复杂度为 $ O(1) $,即常数时间。 - **最坏情况**:当所有键都映射到同一个存储桶时,这些操作的时间复杂度退化为 $ O(n) $,其中 $ n $ 是元素总数。这种情况通常发生在哈希函数设计不佳或负载因子过高的情况下[^4]。 ### 无序关联容器的优势 - **快速访问**:由于底层使用哈希表,无序关联容器支持平均 $ O(1) $ 的查找、插入和删除操作。 - **灵活性**:支持用户自定义哈希函数和比较函数,使得容器能够适应各种类型的数据。 - **动态扩容**:当元素数量超过当前容量时,容器会自动进行重新散列,以保持较低的负载因子并优化性能。 ### 示例代码 以下是一个使用 `std::unordered_map` 的简单示例: ```cpp #include <iostream> #include <unordered_map> int main() { // 创建一个无序映射,键为字符串,值为整数 std::unordered_map<std::string, int> myMap; // 插入键值对 myMap["apple"] = 5; myMap["banana"] = 3; myMap["orange"] = 8; // 查找并输出键值对 std::cout << "apple: " << myMap.find("apple")->second << std::endl; std::cout << "banana: " << myMap.find("banana")->second << std::endl; std::cout << "orange: " << myMap.find("orange")->second << std::endl; return 0; } ``` ### 总结 无序关联容器的底层数据结构是哈希表,它通过高效的哈希函数和存储桶管理实现了快速的插入、删除和查找操作。然而,为了确保最佳性能,需要合理选择哈希函数并管理负载因子。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值