关联式容器的概念
关联式容器也是用来存储数据的,但与序列式容器不同,它存储的是的键值对,在数据检索时比序列式容器效率高
键值对的概念
用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值,value表示与key对应的信息。例如apple它有一个对应的中文名称,它和中文名称一一对应,即通过该单词在词典中可以找到对应的中文名称。
树形结构的关联式容器
- map
map中放的是的键值对,key是唯一的,不能重复
map的使用:
1、std::map的模板参数说明
template< class Key,
class T,
class Compare=less< Key >
class Alloc=allocator< pair >
> class map;
其中key指键值对中key的类型,T指键值对中value的类型,Compare指比较器的类型,map中的元素按照key来比较,一般该参数不用传递,如果是自定义,需要显式传递,Alloc指通过空间配置器来申请底层空间,不需要用户传递,除非用户不想使用标准库提供的空间配置器
在使用map时,需要包含头文件。
2、map的构造
有三种构造方式,分别为构造空的map,用[first,last)区间中的元素构造,还有拷贝构造
3、map的迭代器
begin+end;rbegin+rend
4、map的容量与元素访问
判空、返回有效元素个数、返回key对应的value
5、map中元素的修改
(1)pair insert ( const value_type& x ),表示在map中插入键值对x,注意x是一个键值对,返回值也是键值对:iterator代表新插入元素的位置,bool代表是否插入成功
(2)iterator insert ( iterator position, const value_type& x ),表示在position位置插入值为x的键值对,返回该键值对在map中的位置,注意:元素不一定必须插在position位置
(3)template
void insert ( InputIterator first, InputIterator last ),表示在map中插入[first, last)区间中的元素
(4)void erase ( iterator position ),表示删除position位置上的元素
(5)size_type erase ( const key_type& x ),表示删除键值为x的元素
(6)void erase ( iterator first, iterator last ) ,表示删除[first, last)区间中的元素
(7)void swap ( map& mp ),表示交换两个map中的元素
(8)void clear ( ) ,表示将map中的元素清空
(9)iterator find ( const key_type& x ),表示在map中插入key为x的元素,找到返回该元素的位置的迭代器,否则返回end
(10)const_iterator find ( const key_type& x ) const,表示在map中插入key为x的元素,找到返回该元素的位置的const迭代器,否则返回cend
(11)size_type count ( const key_type& x ) const,表示返回key为x的键值在map中的个数,注意map中key是唯一的,因此该函数的返回值要么为0,要么为1,因此也可以用该函数来检测一个key是否在map中
例如:
#include
using namespace std;
#include
注意:当[]中的key在map中不存在的情况下,map将构成一个键值对插入到map中,返回默认value;at()函数直接抛异常。
- multimap
multimap与map的区别是也放的是的键值对,但是key可以重复
例如:
int main()
{
multimap m;
m.insert(pair("apple", "苹果"));
m.insert(make_pair("orange", "橘子"));
m.insert(make_pair("banana", "香蕉"));
m.insert(make_pair("peach", "桃子"));
m.insert(make_pair("apple", "pingguo"));
//cout << m["peach"] << endl;//无法使用下标运算符,因为key值可以重复,无法具体访问
cout << m.size() << endl;
cout << m.count("apple");//这时就是2,因为有两个key为apple的
for (auto e : m)
cout << e.first << "---->" << e.second << endl;
m.erase("peach");//删除,括号中是迭代器类型,相当于key
if ((m.find("peach")) != m.end())//end是左闭右开的,表示没有元素
{
cout << "存在" << endl;
}
else
cout << "不存在" << endl;
multimap::iterator it = m.begin();
while (it != m.end())
{
cout << it->first << "--->" << it->second << endl;
++it;
}
cout << endl;
auto rit = m.rbegin();
while (rit != m.rend())//反向迭代器
{
cout << rit->first << "--->" << rit->second << endl;
++rit;
}
cout << endl;
for (auto e : m)
cout << e.first << "---->" << e.second << endl;
m.clear();//清空
return 0;
}
注意:multimap无法使用下标运算符,因为key可以重复,无法具体访问。
- set
set是按照一定次序存取元素的容器,set中存key,每个key是唯一的,set中的元素不能在容器中修改,但是可以进行插入和删除,通过set的迭代器进行遍历,可以得到有序序列,set的底层使用红黑树来实现。
set的使用
例如:
#include
int main()
{
int array[] = { 4, 4, 3, 3, 0, 0, 9, 9, 1, 1, 3, 3, 2, 2, 5, 5, 8, 8, 6, 6, 7, 7 };
set s;
for (auto e : array)
s.insert(e);//0,1,2,3,4,5,6,7,8,9,所以set也有去除重复的作用
cout << s.size() << endl;
if (s.find(3) != s.end())
cout << "3 is in set" << endl;
else
cout << "3 is not in set" << endl;
s.erase(3);
cout << s.count(3) << endl;
auto it = s.begin();
while (it != s.end())
{
cout << *it;
++it;
}
cout << endl;
return 0;
}
注意:set有去除重复的作用。
- multiset
multiset的使用与set大致相同,但是它可以存放重复的元素,例如:
int main()
{
int array[] = { 4, 4, 3, 3, 0, 0, 9, 9, 1, 1, 3, 3, 2, 2, 5, 5, 8, 8, 6, 6, 7, 7 };
multiset s;
for (auto e : array)
s.insert(e);//0,1,2,3,4,5,6,7,8,9,所以set也有去除重复的作用
cout << s.size() << endl;//multiset可以存在重复的元素
cout << s.count(3) << endl;
auto it = s.begin();
while (it != s.end())
{
cout << *it;
++it;
}
cout << endl;
return 0;
}
map和set相关源代码(github)
https://github.com/wangbiy/C-/tree/master/test_2019_10_8/test_2019_10_8