关联式容器(map,set,multimap,multiset)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/liuyuchen282828/article/details/102508702

关联式概念

  • STL中的部分容器,比如:vector、list、deque、forward_list(C++11)等,这 些容器统称为序列式容器,因为其底层为线性序列的数据结构,里面存储的是元素本身。
  • 关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是<key, value>结构的键值对在数据检索时比序列式容器效率更高。
二叉搜索平衡结构:

关于key有序的序列,时间复杂度O(logN)

  • map<key,value> 要求:key一定不能重复
  • set:key 要求:key一定不可以重复
  • multimap:<key,value> key是可以重复的
  • multiset:key,key可以重复

键值对

用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值, value表示与key对应的信息。比如:现在要建立一个英汉互译的字典,那该字典中必然有英文单词与其对应 的中文含义,而且,英文单词与其中文含义是一一对应的关系,即通过该应该单词,在词典中就可以找到与 其对应的中文含义

SGI—STL中键值对的底层实现
 template <class T1, class T2> 
 struct pair 
 { 
	  typedef T1 first_type;  
	  typedef T2 second_type;
	 
	T1 first;  
	T2 second;  
pair()     
	  : first(T1())      
	  , second(T2())  
 	  {
 	  }      
pair(const T1& a, const T2& b)
      : first(a)
     , second(b) 
      {
      }
 }; 

map

  1. map是关联容器,它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元素。
  2. 在map中,键值key通常用于排序和惟一地标识元素,而值value中存储与此键值key关联的内容。键值 key和值value的类型可能不同,并且在map的内部,key与value通过成员类型value_type绑定在一起, 为其取别名称为pair: typedef pair value_type;
  3. 在内部,map中的元素总是按照键值key进行比较排序的。
  4. map中通过键值访问单个元素的速度通常比unordered_map容器慢,但map允许根据顺序对元素进行 直接迭代(即对map中的元素进行迭代时,可以得到一个有序的序列)。
  5. map支持下标访问符,即在[]中放入key,就可以找到与key对应的value。
  6. map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))。

在这里插入图片描述

map::insert()

在这里插入图片描述
通过insert插入数据有两种方式

  1. pair<类型,类型>(数据,数据)
  2. make_pair(数据,数据)

还可以通过下标运算符[]
对于map来说,如果我们提供的key不存在的情况下,他就会插入这个数据
因为它的下标运算符的底层是这样实现的

(*((this->insert(make_pair(k,mapped_type()))).first)).second 

如果key已经存在了,他就不会插入

void TestMap()
{
	map<string, string>m;
	m.insert(pair<string,string>("宋江","及时雨"));
	m.insert(pair<string, string>("李逵", "黑旋风"));

	//pair<iterator,bool>
	//iterator:代表map中的一个key-value的键值对
	//bool:insert插入是否成功
	auto ret = m.insert(make_pair("孙二娘","母夜叉"));
	if (ret.second){
		cout << (*ret.first).first << "--->" << ret.first->second << endl;
	}
	ret = m.insert(make_pair("李逵", "铁牛"));
	//key 已经存在不会插入
	cout << (*ret.first).first << "--->" << ret.first->second << endl;

	cout << m.size() << endl;

	cout << m["李逵"] << endl; //把value返回来
	//用户提供key---->[]返回key所对应的value
	m["李逵"] = "铁牛";  //修改value
	cout << m["李逵"] << endl;
	m["林冲"] = "豹子头";
	cout << m.size() << endl;
}

下标运算符为什么要用insert?
因为如果key不存在的话,返回值就不好返回了,因为如果key存在返回存在的,如果key不存在插入key和一个默认的value

void TestMap2()
{
	int array[] = { 3, 1, 9, 4, 0, 7, 6, 2, 5 };
	map<int, int>m;
	for (auto e : array){
		m.insert(make_pair(e, e));
	}

	//测试按照迭代器方式进行遍历,能否得到一个关于key有序的序列
	auto it = m.begin();
	while (it != m.end())
	{
		cout << it->first << "---->" << it->second << endl;
		++it;
	}
	cout << endl;

	for (auto& e : m)
	{
		cout << e.first << "---->" << e.second << endl;
	}
	cout << endl;
}

key是有序的,但是value就不一定
其余的功能演示参考:map的其他功能演示

set

set相关接口的演示

set容器没有下标预算符.
set:key,key一定是唯一的
set 最主要的功能是去重,并排序

测试set

int main()
{
	int array[] = { 3, 1, 3, 4, 5, 6, 7, 8, 9, 0, 9, 4, 0, 7, 6, 2, 5, 8 };
	set<int>s;
	for (auto e : array)
		s.insert(e);
	cout << s.size() << endl;

	for (auto e : s)
		cout << e << " ";
	cout << endl;
	system("pause");
	return 0;
}

在这里插入图片描述

multimap

multimap基本操作

注意事项

  1. multimap中的key是可以重复的。
  2. multimap中的元素默认将key按照小于来比较
  3. multimap中没有重载operator[]操作
  4. 使用时与map包含的头文件相同

#include #include

void TestMultimap1() 
{
 multimap<string, string> m; 
 m.insert(make_pair("李逵", "黑旋风")); 
 m.insert(make_pair("林冲", "豹子头")); 
 m.insert(make_pair("鲁达", "花和尚"));
  // 尝试插入key相同的元素 
  
 m.insert(make_pair("李逵", "铁牛")); 
 cout << m.size() << endl;
 
for (auto& e : m)    
cout << "<" << e.first << "," << e.second << ">" << endl;
    // key为李逵的元素有多少个    
    cout << m.count("李逵") << endl; return 0; 
}
 void TestMultimap2() 
 {    
 	 multimap<int, int> m;
   for (int i = 0; i < 10; ++i)    
   m.insert(pair<int, int>(i, i));
	for (auto& e : m)    
	cout << e.first << "--->" << e.second << endl; 
	cout << endl;
 
	 // 返回m中大于等于5的第一个元素 
 	auto it = m.lower_bound(5); 
 	cout << it->first << "--->" << it->second << endl;
 
 	// 返回m中大于5的元素 
 	it = m.upper_bound(5); 
 	cout << it->first << "--->" << it->second << endl;
 }

multiset

multiset的基本操作

multiset:只存储key,key可以重复,关于key有序

测试

int main()
{
	int array[] = { 3, 1, 3, 4, 5, 6, 7, 8, 9, 0, 9, 4, 0, 7, 6, 2, 5, 8 };
		multiset<int>s;
		for (auto e : array)
			s.insert(e);
		cout << s.size() << endl;
	
		for (auto e : s)
			cout << e << " ";
		cout << endl;
	system("pause");
	return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/liuyuchen282828/article/details/102508702