C++:map,unordered_map,set和unordered_set

一、map

内部实现机理

map内部实现了一个 红黑树, map中的元素是按照二叉搜索树存储的,红黑树具有自动排序的功能,使用中序遍历可将键值按照从小到大遍历出来。

优点:

  • 有序性,这是map结构最大的优点,其元素的有序性在很多应用中都会简化很多的操作;
  • 红黑树,内部实现一个红黑树使得map的很多操作在O(logN)的时间复杂度下就可以实现,因此效率非常的高。

缺点:

  • 空间占用率高,因为map内部实现了红黑树,虽然提高了运行效率(低于unorder_map),但是因为每一个节点都需要额外保存父节点、孩子节点和红/黑性质,使得每一个节点都占用大量的空间(但占用的内存比unorder_map低)

**适用处:**对于那些数据存储有顺序要求的问题,用map会更高效一些

	vector<int> list = { 5,14,34,22,39,5 };
	map<int, int> map;
	for (int i = list.size() - 1; i >= 0; i--) {
		map[i] = list[i];  //倒序插入
	}
	for (auto i = map.begin(); i != map.end(); i++) {
		cout << i->first << ' ' << i->second << endl;  //输出的数是有序的且有两个5
	}
	if (map.find(3) != map.end()) {
		cout << "find key=" << map.find(3)->first << ", value=" << map.find(3)->second << endl;
	}
	if (map.count(5) > 0) {  //m.count(n)计算下标为n的位置有无数据,有返回1,无返回0
		cout << "count 5: " << map.count(5) << endl;  //find()和count()的输入参数都是key值
	}

map是基于RBT的,因此元素是有序存储的(默认按 键 的升序排列)。

输出结果:
在这里插入图片描述

二、unordered_map

内部实现机理

unordered_map内部实现了一个哈希表, 其元素的排列顺序是无序的。

优点: 因为内部实现了哈希表,因此其查找速度非常的快(运行效率快于map)
缺点: 哈希表的建立比较耗费时间(unorder_map占用的内存比map要高)
适用处:对于查找问题,unordered_map会更加高效一些,因此遇到查找问题,常会考虑一下用unordered_map

	vector<int> list = { 5,14,34,22,39,5 };
	unordered_map<int, int> map;
	for (int i = list.size()-1; i>=0; i--) {
		map[i] = list[i];  //倒序插入
	}
	cout << map[0] << endl;
	for (unordered_map<int, int>::iterator i = map.begin(); i != map.end(); i++) {
		cout << i->first << ' ' << i->second << endl;  //输出的数是有序的且有两个5
	}
	if (map.find(3) != map.end()) {
		cout << "find key=" << map.find(3)->first << ", value=" << map.find(3)->second << endl;
	}
	if (map.count(5) > 0) {  //m.count(n)计算下标为n的位置有无数据,有返回1,无返回0
		cout << "find 5: " << map.count(5) << endl;  //find()和count()的输入都是key值
	}

unordered_map 是基于hash表的,因此元素是无序存储的( 不按键 升序排列)。

输出结果:
在这里插入图片描述

三、set

内部实现机理

set实现了红黑树的平衡二叉检索树的数据结构,插入元素时,它会自动调整二叉树的排列,把元素放到适当的位置,在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序。另外使用中序遍历可将键值按照从小到大遍历出来。


	vector<int> list = { 5,14,34,22,39,5 };
	set<int> set1;
	for (int i = list.size() - 1; i >= 0; i--) {
		set1.insert(list[i]);  //倒序插入
	}
	for (auto i = set1.begin(); i != set1.end(); i++) {
		cout << *i << endl;  //输出的数是有序的且只有一个5
	}
	cout << "find 5: " << *set1.find(5) << endl;
	cout <<"count 5: " << set1.count(5) << endl;

set 是基于RBT的,因此元素是顺序存储的(默认按 键值 升序排列)。

输出结果:
在这里插入图片描述

四、unordered_set
内部实现机理

unordered_set的内部实现了一个 哈希表,因此, 其元素的排列顺序是无序的。


	vector<int> list = { 5,14,34,22,39,5 };
	unordered_set<int> set;
	for (int i = list.size() - 1; i >= 0; i--) {
		set.insert(list[i]);  //倒序插入
	}
	for (unordered_set<int>::iterator i = set.begin(); i != set.end(); i++) {
		cout << *i << endl;  //输出的数是无序的且只有一个5
	}
	cout << "find 39: " << *set.find(39) << endl;
	cout << "count 14:" << set.count(14) << endl;

unordered_set 是基于hash表的,因此元素是无序存储的( 不按键值 升序排列)。
在这里插入图片描述
https://blog.csdn.net/bryant_zhang/article/details/111600209

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值