面试题map/unordered相关

目录

map/set与unordered_map/unorder_set的区别

区别1:有序性区别

区别2:底层数据结构区别

区别3:迭代器区别

区别4:性能区别

性能测试案例

少量数据对比结果

大量数据对比结果

性能测试小结


map/set与unordered_map/unorder_set的区别

区别1:有序性区别

对于map/set根据键值会默认按升序进行排序。对于unorder_xx系列是无序的。

区别2:底层数据结构区别

对于map/set底层实现数据结构是一个平衡二叉树(红黑树),对于unordered系类底层实现是哈希表,通过hash表把key映射到对应的下标,实现快速访问。

区别3:迭代器区别

对于map/set支持双向迭代器,支持it++,it--。而对于unordered系列只支持单项迭代器,只能++不能--。原因:对于红黑树节点间存在全局有序的前驱后继关系,因此迭代器可前后移动,是双向迭代器。而对于hash表,遍历顺序由哈希分布决定,无全局有序前驱关系,后退操作无法高效实现,因此仅支持前向迭代器

区别4:性能区别

map/set底层一棵红黑树(平衡二叉搜索树),对于增删查改的性能测试大概稳定在O(logN)。

而对于unordered系列的增删查改性能平均在O(1)的。

性能测试案例

我们以一个容器对比set/unordered_set对容器增删查性能做对比。

cpp 复制代码
#include <iostream>
#include <set>
#include <unordered_set>
#include <time.h>
using namespace std;

int main()
{
	int N = 100;
	vector<int> v;
	v.reserve(N);
	srand((unsigned int)time(NULL));
	//随机生成N个数字
	for (int i = 0; i < N; i++)
	{
		v.push_back(rand());
	}

	/****************插入效率测试****************/
	//将这N个数插入set容器
	set<int> s;
	clock_t begin1 = clock();
	for (auto e : v)
	{
		s.insert(e);
	}
	clock_t end1 = clock();

	//将这N个数插入unordered_set容器
	unordered_set<int> us;
	clock_t begin2 = clock();
	for (auto e : v)
	{
		us.insert(e);
	}
	clock_t end2 = clock();

	//分别输出插入set容器和unordered_set容器所用的时间
	cout << "插入到set容器时间: " << end1 - begin1 << endl;
	cout << "插入到unordered_set容器的时间: " << end2 - begin2 << endl;

	/****************查找效率测试****************/
	//在set容器中查找这N个数
	clock_t begin3 = clock();
	for (auto e : v)
	{
		s.find(e);
	}
	clock_t end3 = clock();

	//在unordered_set容器中查找这N个数
	clock_t begin4 = clock();
	for (auto e : v)
	{
		us.find(e);
	}
	clock_t end4 = clock();

	//分别输出在set容器和unordered_set容器中查找这N个数所用的时间
	cout << "用set遍历所有元素时间: " << end3 - begin3 << endl;
	cout << "用unordered_set遍历所有元素时间: " << end4 - begin4 << endl;

	/****************删除效率测试****************/
	//将这N个数从set容器中删除
	clock_t begin5 = clock();
	for (auto e : v)
	{
		s.erase(e);
	}
	clock_t end5 = clock();

	//将这N个数从unordered_set容器中删除
	clock_t begin6 = clock();
	for (auto e : v)
	{
		us.erase(e);
	}
	clock_t end6 = clock();

	//分别输出将这N个数从set容器和unordered_set容器中删除所用的时间
	cout << "用set删除所有元素时间 " << end5 - begin5 << endl;
	cout << "用unordered_set删除所有元素时间: " << end6 - begin6 << endl;
	return 0;
}

少量数据对比结果

大量数据对比结果

性能测试小结

对于上边测试结果我们可以看到:

当数据量特别小的时候虽然有差异但可以忽略不计,我们可以认为两个容器性能差不多。

但当数据量很大的时候对于unordered容器的性能明显比set/map容器性能强的多。

相关推荐
不会就选b40 分钟前
数据结构之排序
数据结构
我不会起名字3223 小时前
一天一道算法题(34):回溯法的经典例题(子集)
java·数据结构·python·算法·golang·深度优先·力扣
Logic1016 小时前
C语言/数据结构位运算题解:异或XOR找出货船中的“独特载货量“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
彧azz7 小时前
DFS与BFS:图遍历的两大核心算法
数据结构·学习·算法·深度优先·广度优先
青山木8 小时前
Hot 100 --- 最长递增子序列
java·数据结构·算法·leetcode·动态规划
土司大王8 小时前
LeetCode hot100——33.搜索旋转排序数组:Java 二分模板与 O(log n) 实现
数据结构·算法·leetcode
程序员阿鹏9 小时前
如何实现MySQL分库分表?
数据结构·数据库·sql·mysql·缓存
ysu_031410 小时前
08-二叉树遍历:四种方式详解
c语言·数据结构·算法·leetcode
Lyyaoo.11 小时前
【二分查找】【中等】搜索二维矩阵/排序数组的第一位和最后位置/搜索旋转排序数组/旋转排序数组中的最小值
java·数据结构·算法
Lyyaoo.12 小时前
【二分查找】【困难】寻找两个有序数组的中位数
java·数据结构·算法