map/set/multi_map/multi_set/unorder_map/unorder_set总结

本文深入探讨了STL容器中的map、set、multi_map、multi_set、unordered_map和unordered_set的底层实现原理及其使用方法。包括红黑树和哈希表的数据结构特性,以及自定义类型在这些容器中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

map/set/multi_map/multi_sep底层实现是加头节点的红黑树,元素之间有序,当存放的是自定义类型的时候要重载operator<,中序遍历的时候是有序的。增删查的时间复杂度都是O(lgN)

map存放的是键值对<key,value>,,key唯一,value可以重复,不能修改key的值,可以先删除旧的值,再添加新的值,value的值可以修改。

set用户存放的是值,但是底层存放的仍能存放的是键值对,只不过key=value,同样的值是唯一的,不能随便修改value.

mulit_map/multi_set与map/set相比,大部分都是相同的,只是存放的元素可以不唯一,可以重复。


set代码:

#include<string>  
#include<iostream>  
#include<set>  
using namespace  std;


struct person  
{  
	string name;  
	int age;  

	person(string name, int age)  
	{  
		this->name =  name;  
		this->age = age;  
	}  

	bool operator < (const person& p) const     //key值比较
	{  
		return this->age < p.age;   
	}  

};  


int main()  
{  
	set<person> m;
	person p1("Tom1",28);  
	person p2("Tom2",23);  
	person p3("Tom3",22);  
	person p4("Tom4",20);  
	person p5("Tom5",24);  
	m.insert(p3);  
	m.insert(p1);   
	m.insert(p2); 
	m.insert(p4);
	m.insert(p5);  


	for(set<person>::iterator iter = m.begin(); iter != m.end(); iter++)  
	{  
		cout<<iter->name<<"\t"<<iter->age<<endl;  
	}  

	system("pause");
	return 0;  
} 



map代码:

#include<string>  
#include<iostream>  
#include<map>  
using namespace  std;


struct person  
{  
	string name;  
	int age;  

	person(string name, int age)  
	{  
		this->name =  name;  
		this->age = age;  
	}  

	bool operator < (const person& p) const   //key值的比较。比较值唯一。
	{  
		return this->age < p.age;   
	}  
	
};  

map<person,int> m;  
int main()  
{  
	
	person p1("Tom1",20);  
	person p2("Tom2",22);  
	person p3("Tom3",22);  
	person p4("Tom4",23);  
	person p5("Tom5",24);  
	m.insert(make_pair(p3, 100));  
	m.insert(make_pair(p4, 100));  
	m.insert(make_pair(p5, 100));  
	m.insert(make_pair(p1, 100));  
	m.insert(make_pair(p2, 100));  

	for(map<person, int>::iterator iter = m.begin(); iter != m.end(); iter++)  
	{  
		cout<<iter->first.name<<"\t"<<iter->first.age<<endl;  
	}  

	system("pause");
	return 0;  
} 


unordered_map/unordered_set底层实现用了哈希表,

(1)unordered_set存放的是value,unorder_map也是存储的key-value的值,可以通过key快速索引到value,但是不会根据key的大小进行排序,增删查的时间复杂度都是O(1)

(2)同样不能修改key值当存放的是自定义的元素类型的时候,需要定义hash_value函数并且重载operator==,重载operator==是因为,如果两个元素的通过哈希函数计算出的值相同,并不能断定这两个元素就相同,必须再调用operator==。

(3)散列值相同的被存储在一个桶里。当散列容器中有大量数据时,同一个桶里的数据也会增多,造成访问冲突,降低性能。为了提高散列容器的性能,unordered库会在插入元素是自动增加桶的数量,不需要用户指定。但是,用户也可以在构造函数或者rehash()函数中,指定最小的桶的数量

哈希表结构如下图:


#include<string>  
#include<iostream>  
#include<unordered_map>  
#include<boost/unordered_map.hpp>

using namespace std;  

struct person  
{  
	string name;  
	int age;  

	person(string name, int age)  
	{  
		this->name =  name;  
		this->age = age;  
	}  

	bool operator== (const person& p) const  
	{  
		return name==p.name && age==p.age;  
	}  
};  

size_t hash_value(const person& p)  
{  
	size_t seed = 0;  
	std::hash_combine(seed, std::hash_value(p.name));  
	std::hash_combine(seed, std::hash_value(p.age));  
	return seed;  
}  

int main()  
{  
	typedef std::unordered_map<person,int> umap;  
	umap m;  
	person p1("Tom1",20);  
	person p2("Tom2",22);  
	person p3("Tom3",22);  
	person p4("Tom4",23);  
	person p5("Tom5",24);  
	m.insert(umap::value_type(p3, 100));  
	m.insert(umap::value_type(p4, 100));  
	m.insert(umap::value_type(p5, 100));  
	m.insert(umap::value_type(p1, 100));  
	m.insert(umap::value_type(p2, 100));  

	for(umap::iterator iter = m.begin(); iter != m.end(); iter++)  
	{  
		cout<<iter->first.name<<"\t"<<iter->first.age<<endl;  
	}  

	return 0;  
}  

结果:

Tom1    20
Tom5    24
Tom4    23
Tom2    22
Tom3    22



unordered_map/unordered_set  与map/set结论:

运行效率方面:unordered_map/unordered_set 最高,而map/set效率较低但 提供了稳定效率和有序的序列。

占用内存方面:map/set内存占用略低,unordered_map/unordered_set内存占用略高,而且是线性成比例的。

需要无序容器,快速查找删除,不担心略高的内存时用unordered_map;有序容器稳定查找删除效率,内存很在意时候用map



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值