C++进阶:STL之树形结构的关联式容器1(接口与使用)

关联式容器的概念

关联式容器也是用来存储数据的,但与序列式容器不同,它存储的是的键值对,在数据检索时比序列式容器效率高

键值对的概念

用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量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 
#include 
int main()
{
	map m;
	//C++98
	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"));//相同key值的无法插入
	cout << m["peach"] << endl;
	cout << m["straberry"] << endl;//打印的是空的字符串
	//当[]中的key在map中不存在的情况下,
	//map将构成一个键值对插入到map中,返回默认value
	cout << m.size() << endl;//5个键值对

	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;

	map::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;
	return 0;
}

注意:当[]中的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

你可能感兴趣的:(#,C++)