STL封装了许多复杂的数据结构算法和大量常用数据结构操作。vector封装数组,list封装了链表,map和set封装了红黑树(平衡二叉搜索树)等。
Set和Map的区别在于Set只含有Key,而Map有一个Key和Key所对应的Value两个元素。
非常高效的平衡检索二叉树:红黑树,他的插入删除效率比其他序列容器高是因为不需要做内存拷贝和内存移动,而直接替换指向节点的指针即可。
Set
set : 去重 + 排升序 ; (底层是 红黑树 )
multiset : 不去重 + 排升序 ; (底层是 红黑树 )
set使用方法:
begin() ,返回set容器的第一个迭代器
end() ,返回set容器的最后一个迭代器
clear() ,删除set容器中的所有的元素
empty() ,判断set容器是否为空
max_size() ,返回set容器可能包含的元素最大个数
size() ,返回当前set容器中的元素个数
rbegin ,返回的值和end()相同
rend() ,返回的值和rbegin()相同
————————————————
set<int> s;
s.insert(1);
s.insert(2);
s.insert(3);
s.insert(1);
cout<<"set 的 size 值为 :"<<s.size()<<endl;
cout<<"set 的 maxsize的值为 :"<<s.max_size()<<endl;
cout<<"set 中的第一个元素是 :"<<*s.begin()<<endl;
cout<<"set 中的最后一个元素是:"<<*s.end()<<endl;
set容器带有自动去从与排序的功能,所以容器中每个元素只会保留一个。
第一个元素为1,最后一个为3
Map
map翻译为映射,也是常见的STL容器
在定义数组时(如int array[100]),其实是定义了一个从int型到int型的映射
比如array[0]=25、array[4]=36就分别是将0映射到25、将4映射到36
一个double型数组则是将int型映射到double型,如db[0]=3.14,double[1]=0.01
但是,无论是什么类型它总是将int型映射到其他类型.
1、map的定义
map<typename1,typename2>mp;
与其他STL容器在定义上不一样,因为map需要确定映射前类型(键key)和映射后类型(值value)
所以需要在<>内填写两个类型
其中一个是键的类型
第二个是值得类型
如果是int型映射到int型,就相当于是普通的int型数组
map<string,int>mp
但是如果是字符串到整型的映射,必须是string而不是char数组
这时因为char数组作为数组是不能被作为键值的。所以字符串作映射,只能用string
因为map的每一对映射都有两个typename
这决定了必须通过一个it来同时访问键和值
事实上,map可以使用it->first来访问键
使用it->second来访问值
map<int, string>::iterator it 是声明一个 迭代器
map<int, string> it 是 声明一个map容器
/直接用auto可以在声明变量的时候根据变量初始值的类型自动为此变量选择匹配的类型/不需要用td::vectorstd::string::iterator i来声明
for (auto i = vs.begin(); i != vs.end(); i++)
//… cout<first<<" "<second<<endl;
}
#include<map>
using namespace std;
int main()
{ map<int, string> mapStudent;
mapStudent[1] = "student_one";
mapStudent[2] = "student_two";
mapStudent[3] = "student_three";
map<char,int>mp;
mp['m']=20;
mp['r']=30;
mp['a']=40;
for(map<char,int>::iterator it=mp.begin();it!=mp.end();it++)
{
printf("%c %d\n",it->first,it->second);
}
return 0;
}
map会以键的大小从小到大的顺序自动排序
即按照a<m<r的顺序排列这三对映射
这是因为map内部是使用红黑树(set也是)
在建立映射的过程中会自动实现从小到大的排序功能
map的键和值是唯一的,而如果一个键需要对应多个值就只能用multimap
注意:如果key在map里面有的话,不会覆盖之前的value,还有一种方法,可以通过value = map[key],利用[]=来实现覆盖,进行数据的更新。
int main()
{
map<int, string> m;
m.insert(make_pair(1, "Lixin1"));
m.insert(pair<int, string>(2, "Lixin2"));
m.insert(pair<int, string>(3, "Lixin3"));
cout << "befor insert key=1, value = " << m[1] << endl;
map<int, string>::iterator it;
m.insert(make_pair(1, "Lixin4"));
for (it = m.begin(); it != m.end(); it++){
cout << "key is " << it->first << " value is " << it->second << endl;
}
//insert方式,重复的key会直接被放弃,而不是进行覆盖(这一点与Java不同)
cout << "after insert , value = " <<m[1] << endl;
//[]方式是可以覆盖的
m[1] = "Lixin5";
cout << "after []= , value = " << m[1] << endl;
//find key,返回迭代器,存在先erase删掉,重新插入,可以更新
it = m.find(1);
if (it != m.end()){
m.erase(it);
m.insert(pair<int, string>(1, "Lixin6"));
cout << "after erase , " << " value = " << m[1] << endl;
}
}