C++ map、multimap、unordered_map
map与unordered_map相比:
map底层实现为红黑数,unordered_map底层实现为哈希表,两者均不能有重复的建,均支持[]运算符
map与multimap相比:
两者底层实现均为红黑树,但是multimap支持重复的键,不支持[]运算符。
内部实现机理不同
map: map内部实现了一个红黑树(红黑树是非严格平衡二叉搜索树,而AVL是严格平衡二叉搜索树),红黑树具有自动排序的功能,因此map内部的所有元素都是有序的,红黑树的每一个节点都代表着map的一个元素。因此,对于map进行的查找,删除,添加等一系列的操作都相当于是对红黑树进行的操作。map中的元素是按照二叉搜索树(又名二叉查找树、二叉排序树,特点就是左子树上所有节点的键值都小于根节点的键值,右子树所有节点的键值都大于根节点的键值)存储的,使用中序遍历可将键值按照从小到大遍历出来。
unordered_map: unordered_map内部实现了一个哈希表(也叫散列表,通过把关键码值映射到Hash表中一个位置来访问记录,查找的时间复杂度可达到O(1),其在海量数据处理中有着广泛应用)。因此,其元素的排列顺序是无序的。哈希表详细介绍
优缺点以及适用处
map:
优点:
有序性,这是map结构最大的优点,其元素的有序性在很多应用中都会简化很多的操作
红黑树,内部实现一个红黑书使得map的很多操作在lgn的时间复杂度下就可以实现,因此效率非常的高
缺点: 空间占用率高,因为map内部实现了红黑树,虽然提高了运行效率,但是因为每一个节点都需要额外保存父节点、孩子节点和红/黑性质,使得每一个节点都占用大量的空间
适用处:对于那些有顺序要求的问题,用map会更高效一些
unordered_map:
优点: 因为内部实现了哈希表,因此其查找速度非常的快
缺点: 哈希表的建立比较耗费时间
适用处:对于查找问题,unordered_map会更加高效一些,因此遇到查找问题,常会考虑一下用unordered_map
总结:
内存占有率的问题就转化成红黑树 VS hash表 , 还是unorder_map占用的内存要高。
但是unordered_map执行效率要比map高很多
对于unordered_map或unordered_set容器,其遍历顺序与创建该容器时输入的顺序不一定相同,因为遍历是按照哈希表从前往后依次遍历的
map和unordered_map的使用
unordered_map的用法和map是一样的,提供了 insert,size,count等操作,并且里面的元素也是以pair类型来存贮的。其底层实现是完全不同的,上方已经解释了,但是就外部使用来说却是一致的。
map元素的默认值(unordermap也一样)
当map内元素值为int类型或常量时,默认值为0。
当为String类型时,默认值不明,不显示。
- map内元素值为int类型
#include <iostream> #include <map> using namespace std; int main(){ map<int,int> table; table[1]=1; cout<<table[0]<<endl; cout<<table[1]<<endl; return 0; }
运行结果:

int main() { map<int,int> a; multimap<int,int> b; unordered_map<int,int> c; a[1]=20; a[4]=30; a[7]=90; a[5]=10; a[2]=40; auto iter = a.begin(); cout<<"result of map:"<<endl; while(iter!=a.end()) { cout<<iter->first<<","<<iter->second<<endl; ++iter; } cout<<"result of multimap:"<<endl; b.insert(make_pair(1,20));
b.insert(make_pair(1,70)); b.insert(make_pair(4,30)); b.insert(make_pair(7,90)); b.insert(make_pair(5,10)); b.insert(make_pair(2,40)); auto iter1 = b.begin(); while(iter1!=b.end()) { cout<<iter1->first<<","<<iter1->second<<endl; ++iter1; } cout<<"result of unordered_map:"<<endl; c[1]=20; c[4]=30; c[7]=90; c[5]=10; c[2]=40; auto iter2 = c.begin(); while(iter2!=c.end()) { cout<<iter2->first<<","<<iter2->second<<endl; ++iter2; } }



c++ stl multimap基本操作使用技巧详细介绍 C++ stl Multimap 和C++ stl map 很相似,但是MultiMap允许重复的元素。 C++ stl Multimap的基本操作类成员函数列表介绍如下: begin()返回指向第一个元素的迭代器 clear()删除所有元素 count()返回一个元素出现的次数 empty()如果multimap为空则返回真 end()返回一个指向multimap末尾的迭代器 equal_range()返回指向元素的key为指定值的迭代器对 erase()删除元素 find()查找元素 get_allocator()返回multimap的配置器 insert()插入元素 key_comp()返回比较key的函数 lower_bound()返回键值>=给定元素的第一个位置 max_size()返回可以容纳的最大元素个数 rbegin()返回一个指向mulitmap尾部的逆向迭代器 rend()返回一个指向multimap头部的逆向迭代器 size()返回multimap中元素的个数 swap()交换两个multimaps upper_bound()返回键值>给定元素的第一个位置 value_comp()返回比较元素value的函数 #include <map> #include <string> #include <iostream> using namespace std; int main() { ///1. 初始化 multimap<int, string> mapStudent; multimap<int, string>::iterator iter, beg, end; ///2. 添加元素 ///multimap不支持下标操作 mapStudent.insert(pair<int, string>(0, "student_one")); mapStudent.insert(pair<int, string>(0, "student_one_copy"));///一对多 mapStudent.insert(pair<int, string>(1, "student_two")); mapStudent.insert(pair<int, string>(5, "Fear Kubrick")); mapStudent.insert(pair<int, string>(2, "Akemi Homura")); mapStudent.insert(pair<int, string>(-1, "Eren Jaeger")); mapStudent.insert(pair<int, string>(99, "lin")); cout << mapStudent.size() << endl; cout << endl; ///3. 遍历 for (iter = mapStudent.begin(); iter != mapStudent.end(); iter++) cout << iter->first << " " << iter->second << endl; cout << endl; ///4. 单键查询与范围查询 ///单键查询 int count = mapStudent.count(0); iter = mapStudent.find(0); for (int i = 0; i < count; i++, iter++) cout << iter->first << " " << iter->second << endl; cout << endl; ///范围查询 beg = mapStudent.lower_bound(1);/// >=1 end = mapStudent.upper_bound(5);/// <=5 for (; beg != end; beg++) cout << beg->first << " " << beg->second << endl; cout << endl; ///5. 删除 iter = mapStudent.find(1); mapStudent.erase(iter); cout << mapStudent.size() << endl; for (iter = mapStudent.begin(); iter != mapStudent.end(); iter++) cout << iter->first << " " << iter->second << endl; cout << endl; ///6. 判空与清空 if (!mapStudent.empty()) mapStudent.clear(); }

浙公网安备 33010602011771号