set, multiset, unordered_set, map, multimap, unordered_map的区别
set, multiset, unordered_set, map, multimap, unordered_map都是关联型容器
set和multiset以红黑树作为底层实现,不可以通过迭代器来修改元素的值,如果任意改变set元素的值,会破坏set的组织,拥有和list某些相同的特性,进行元素的新增和删除后,操做前的迭代器依然可用。unordered_set与hash_set都是以hash table作为底层实现,通过对插入或者要查询的值通过哈希函数计算,在一定程度上可以在O(1)的时间复杂度内完成操作,unordered_set是在C++11后被引入的标准库,而hash_set并没有,所以说还是多用unordered_set。
可以通过set_intersection计算交集,set_union计算并集,set_difference计算差集,set_symmetric_difference计算对称差集。结果会写入到一个insert_iterator指向的容器中。
map和multimap以红黑树作为底层实现,不可以通过迭代器修改元素的键,但是可以修改元素的值,拥有和list某些相同的特性,进行元素的新增和删除后,操做前的迭代器依然可用。
简单使用:
#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <functional>
#include <set>
#include <unordered_set>
#include <hash_set>
#include <hash_map>
using namespace std;
int main(){
set<int> baseSet{1,2,3,4,5,1,5};
multiset<int> multiSet{1,2,3,4,5,1,5};
unordered_set<int> unorderedSet{1,2,3,4,5,1,5};
unordered_multiset<int> unorderedMultiset{1,2,3,198,100,1,198};
// __gnu_cxx::hash_set<int> hashSet{1,2,3,4,5,1,5}; //编译不通过,不支持列表初始化
__gnu_cxx::hash_set<int> hashSet;
hashSet.insert(1);
hashSet.insert(2);
hashSet.insert(3);
hashSet.insert(4);
hashSet.insert(5);
hashSet.insert(1);
hashSet.insert(5);
// __gnu_cxx::hash_multiset<int> hashMultiSet{1,2,3,4,5,1,5}; //编译不通过,不支持列表初始化
__gnu_cxx::hash_multiset<int> hashMultiSet;
hashMultiSet.insert(1);
hashMultiSet.insert(2);
hashMultiSet.insert(3);
hashMultiSet.insert(4);
hashMultiSet.insert(5);
hashMultiSet.insert(1);
hashMultiSet.insert(5);
map<int,string> baseMap{{1,"aa"},{2,"bb"},{3,"cc"},{1,"dd"},{3,"ee"},{4,"ff"}};
multimap<int,string> multiMap{{1,"aa"},{2,"bb"},{3,"cc"},{1,"dd"},{3,"ee"},{4,"ff"}};
unordered_map<int,string> unorderedMap{{1,"aa"},{2,"bb"},{3,"cc"},{1,"dd"},{3,"ee"},{4,"ff"}};
unordered_multimap<int,string> unorderedMultimap{{1,"aa"},{2,"bb"},{3,"cc"},{1,"dd"},{3,"ee"},{4,"ff"}};
__gnu_cxx::hash_map<int,string> hashMap; //同样不支持列表初始化
hashMap[1] = "aa";
hashMap[2] = "bb";
hashMap[3] = "cc";
hashMap[1] = "dd";
hashMap[3] = "ee";
hashMap.insert(pair<int,string>(4,"ff"));
__gnu_cxx::hash_multimap<int,string> hashMultimap; //同样不支持列表初始化
// hashMultimap[1] = "aa"; // 不支持
hashMultimap.insert(pair<int,string>(1,"aa"));
hashMultimap.insert(pair<int,string>(2,"bb"));
hashMultimap.insert(pair<int,string>(3,"cc"));
hashMultimap.insert(pair<int,string>(1,"dd"));
hashMultimap.insert(pair<int,string>(3,"ee"));
cout<<"baseSet"<<endl;
for(auto i:baseSet)
cout<<i<<" ";
cout<<'\n'<<"multiSet"<<endl;
for(auto i:multiSet)
cout<<i<<" ";
cout<<'\n'<<"unorderedSet"<<endl;
for(auto i:unorderedSet)
cout<<i<<" ";
cout<<'\n'<<"unorderedMultiset"<<endl;
for(auto i:unorderedMultiset)
cout<<i<<" ";
cout<<'\n'<<"hashSet"<<endl;
for(auto i:hashSet)
cout<<i<<" ";
cout<<'\n'<<"hashMultiSet"<<endl;
for(auto i:hashMultiSet)
cout<<i<<" ";
cout<<'\n'<<"baseMap"<<endl;
for(auto i:baseMap)
cout<<i.first<<':'<<i.second<<" ";
cout<<'\n'<<"multiMap"<<endl;
for(auto i:multiMap)
cout<<i.first<<':'<<i.second<<" ";
cout<<'\n'<<"unorderedMap"<<endl;
for(auto i:unorderedMap)
cout<<i.first<<':'<<i.second<<" ";
cout<<'\n'<<"unorderedMultimap"<<endl;
for(auto i:unorderedMultimap)
cout<<i.first<<':'<<i.second<<" ";
cout<<'\n'<<"hashMap"<<endl;
for(auto i:hashMap)
cout<<i.first<<':'<<i.second<<" ";
cout<<'\n'<<"hashMultimap"<<endl;
for(auto i:hashMultimap)
cout<<i.first<<':'<<i.second<<" ";
return 0;
}
输出结果:
baseSet
1 2 3 4 5
multiSet
1 1 2 3 4 5 5
unorderedSet
5 4 3 2 1
unorderedMultiset
198 198 3 2 100 1 1
hashSet
1 2 3 4 5
hashMultiSet
1 1 2 3 4 5 5
baseMap
1:aa 2:bb 3:cc 4:ff
multiMap
1:aa 1:dd 2:bb 3:cc 3:ee 4:ff
unorderedMap
4:ff 3:cc 2:bb 1:aa
unorderedMultimap
4:ff 3:ee 3:cc 2:bb 1:dd 1:aa
hashMap
1:dd 2:bb 3:ee 4:ff
hashMultimap
1:aa 1:dd 2:bb 3:cc 3:ee
Process finished with exit code 0
使用unorder时默认的缺省大小为100,SGI的设计采用的质数193,部分结果可能因为桶的个数足够,才给人一种排序的假象。
参考: