1.set单重集合:不允许key重复
set作为一个容器,也是用来存储同一数据类型的数据类型,并且能从一个数据集合中取出数据;C++ STL中标准关联容器set, multiset, map,multimap内部采用的就是一种非常高效的平衡检索二叉树:红黑树
- 自动排序:在set中每个元素的值都唯一,而且系统默认的比较函数(小于函数)能根据元素的值自动进行排序(也可以自定义)。
- 插入、删除效率高:因为使用的是红黑树,当插入删除集合元素(红黑树节点)时,挪动的是节点指针指向,不涉及内存移动,所以map和set的插入删除效率比用其他序列容器高、插入元素后迭代器也不会失效。
- 查找效率高:在set中查找是使用二分查找,查找次数log2N。也就是说,如果有16个元素,最多需要比较4次就能找到结果,有32个元素,最多比较5次。那么有10000个呢?最多比较的次数为log10000,最多为14次,如果是20000个元素最多不过15次。
#include <iostream>
using namespace std;
#include <set>
template<typename container>
void show(container &con)
{
container::iterator it= con.begin();
while(it!=con.end())
{
std::cout<<*it<<" ";
it++;
}
std::cout<<std::endl;
}
int main()
{
int arr[]={12,33,534,45657,86576754,1};
int len=sizeof(arr)/sizeof(arr[0]);
std::set<int>myset(arr,arr+len);
//show(myset);
//默认排序后输出
for (auto it = myset.cbegin(); it != myset.cend(); it++)
{
cout << *it << " ";
}
cout << endl;
//查询
std::set<int>::iterator fit1=myset.find(12); //二分查找
std::set<int>::iterator fit2=std::find(myset.begin(),myset.end(),12); //顺序遍历
std::set<int,int>::iterator it1=myset.lower_bound(112);//返回第一个大于等于key_value的定位器
std::set<int,int>::iterator it2=myset.upper_bound(112);//返回最后一个大于等于key_value的定位器
//插入
myset.insert(112);
myset.insert(fit1,12); //单重集合不允许键重复,虽然显示插入成功,但是集合还是只有一个12
int count=myset.count(12);
std::cout<<count<<endl; //count=1;
show(myset);
//删除
myset.erase(112);
show(myset);
myset.erase(myset.begin());
show(myset);
myset.erase(myset.begin(),myset.end());
show(myset);
return 0;
}
结果:
1 12 33 534 45657 86576754
1
1 12 33 112 534 45657 86576754
1 12 33 534 45657 86576754
12 33 534 45657 86576754
请按任意键继续. . .
2.multiset多重集合:允许key重复
3.map:单重映射:自动排序、插入/删除效率高、查找效率高
它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。
#include <iostream>
using namespace std;
#include<algorithm>
#include <map>
template<typename container>
void show(container &con)
{
container::iterator it= con.begin();
while(it!=con.end())
{
std::cout<<*it<<" ";
it++;
}
std::cout<<std::endl;
}
int main()
{
//map单重映射key------>value
std::map<int ,int>mymap;
std::pair<int,int>p1(12,43);
std::pair<int,int>p2(152,43);
//插入数据:三种方法;前两种无区别,第三种数组[]插入方式的不同点在于:键值相同的会被后来插入的覆盖,而insert此时是插入不了
mymap.insert(p1); //插入之后还会按照键值大小排序
mymap.insert(p2);
mymap.insert(std::pair<int,int>(1,2));
mymap.insert(std::pair<int,int>(1,3)); //插入失败,键值不能重复;
mymap.insert(std::pair<int,int>(13,2));
//判断是否插入成功:通过pair的第二个变量来知道是否插入成功,它的第一个变量返回的是一个map的迭代器,如果插入成功的话Insert_Pair.second应该是true的,否则为false。
mymap[152]=456;
mymap[52]=756;
mymap[4]=56;
mymap[5]=56;
//输出map中的成员
std::map<int,int>::iterator it=mymap.begin();
while(it!=mymap.end())
{
std::cout<<"@ ";
cout<<it->first<<" "<<it->second<<endl; //@1 2 @12 43 @13 2 @152 43
it++;
}
//也支持find,方法较多;
std::map<int,int>::iterator iter=mymap.find(13);//利用返回的迭代器获取映射数据
if(iter!=mymap.end())
{
std::cout<<"@ "<<iter->first<<"--->"<<iter->second<<endl;
}
//用count函数来判定关键字是否出现,出现返回1,否则返回0;
//删除erase三种方法:按迭代器位置、按区间、按键值
mymap.erase(mymap.begin());
mymap.erase(iter);
mymap.erase(mymap.begin(),mymap.end());
return 0;
}
结果:
@ 1 2
@ 4 56
@ 5 56
@ 12 43
@ 13 2
@ 52 756
@ 152 456
@ 13--->2
请按任意键继续. . .
hash_map和map的区别:
- 构造函数:hash_map需要等于函数;map只需要比较函数(小于函数).
- 存储结构:hash_map采用hash表存储,map一般采用 红黑树(RB Tree) 实现;
什么时候需要用hash_map,什么时候需要用map
- 总体来说,hash_map 查找速度会比map快,属于常数级别;而map的查找速度是log(n)级别。并不一定常数就比log(n)小,hash函数的耗时;在元素达到一定数量级时考虑hash_map。
- 若你对内存使用特别严格,当你的hash_map对象特别多时,hash_map的构造速度较慢。
4.multimap:多重映射
它提供一对多(其中第一个可以称为关键字,每个关键字只能在map中出现多次,第二个称为该关键字的值)的数据处理能力