C++ STL中标准关联容器set, multiset, map, multimap内部采用的就是一种非常高效的平衡检索二叉树。
C++ 11中出现了两种新的关联容器:unordered_set和unordered_map,其内部实现与set和map大有不同,set和map内部实现是基于RB-Tree,而unordered_set和unordered_map内部实现是基于哈希表(hashtable)
在一个unordered_set(map)内部,元素不会按任何顺序排序,而是通过元素值的hash值将元素分组放置到各个槽(Bucker,也可以译为“桶”),这样就能通过元素值快速访问各个对应的元素(均摊耗时为O(1))。而在set(map)中,元素以节点方式存储于红黑树中,故访问元素效率为O(logn)
set
set有mutliset,set,unordered_set。下面依次对其优缺点与使用方法进行相关介绍
set与multiset的区别在于,set中元素不可重复出现,但mutiset可重复插入一个元素。
unordered_set与set相同,即不能重复插入一个。但unordered_set比set的优势在于其
访问单一元素的效率,远高于set。
set使用举例:
#include <iostream>
#include <set>
using namespace std;
set<int> s;
int main()
{
s.insert(1);
s.insert(2);
s.insert(3);
s.insert(4);
s.erase(3);
cout<<s.count(1)<<endl;
cout<<*s.find(2)<<endl;
for(auto x:s)
{
cout<<x<<" ";
}
}
tips:
s.insert(),在s中插入一个元素。
s.erase(),将某一个元素删除。
s.count(),会返回0或1,判断是否存在该元素。
s.find(),会返回元素下标迭代器。(如果元素不存在则会返回s.end())
以上四种为常用函数,至于其他函数可以百度一下。
multiset与unordered_set基本与set使用方法相同,在此便不在赘述。
map
map与set十分相似,区别在于map存储的为键值对(key-value),即为pair类型。例如:pair<string,int>
。同样的map与unordered_map均不能插入key相同的键值对,但multi_map可以。
map使用举例:
#include <iostream>
#include <map>
using namespace std;
map<string,int> s;
int main()
{
s.insert({"a",1});
s.insert({"b",2});
s.insert({"c",3});
s.insert({"d",4});
s.insert({"e",5});
s.erase("d");
auto t=s.find("b");
cout<<t->second<<endl;
for(auto x:s)
{
cout<<x.first<<" "<<x.second<<endl;
}
}
tips:
s.insert({x,val}),在s中插入一组键值对(key-value)。
s.erase(x),将key为x的键值对删除。
s.count(x),会返回0或1,判断是否存key为x的键值对。
s.find(x),会返回key为x的键值对迭代器。(!!如果键值对不存在map与multimap会返回0,但是unordered_map会导致内存溢出。)
以上四种为常用函数,至于其他函数可以百度一下。