STL-12-unordermap和map的不同

需要引入的头文件不同

map: #include < map >
unordered_map: #include < unordered_map >

内部实现机理不同

    map: map内部实现了一个红黑树(红黑树是非严格平衡二叉搜索树,而AVL是严格平衡二叉搜索树),红黑树具有自动排序的功能,因此map内部的所有元素都是有序的,红黑树的每一个节点都代表着map的一个元素。因此,对于map进行的查找,删除,添加等一系列的操作都相当于是对红黑树进行的操作。

    map中的元素是按照二叉搜索树(又名二叉查找树、二叉排序树,特点就是左子树上所有节点的键值都小于根节点的键值,右子树所有节点的键值都大于根节点的键值)存储的,使用中序遍历可将键值按照从小到大遍历出来。

    unordered_map: unordered_map内部实现了一个哈希表(也叫散列表,通过把关键码值映射到Hash表中一个位置来访问记录,查找的时间复杂度可达到O(1),其在海量数据处理中有着广泛应用)。因此,其元素的排列顺序是无序的。

优缺点以及适用处

map

优点:

    有序性,这是map结构最大的优点,其元素的有序性在很多应用中都会简化很多的操作.

    红黑树,内部实现一个红黑书使得map的很多操作在logn的时间复杂度下就可以实现,因此效率非常的高

缺点:

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

    适用于那些有顺序要求的问题,用map会更高效一些.

unordered_map

优点:

    因为内部实现了哈希表,因此其查找速度非常的快

缺点:
    哈希表的建立比较耗费时间
    对于查找问题,unordered_map会更加高效一些,因此遇到查找问题,常会考虑一下用unordered_map

map和unordered_map的使用

    unordered_map的用法和map是一样的,提供了 insert,size,count等操作,并且里面的元素也是以pair类型来存贮的。其底层实现是完全不同的,上方已经解释了,但是就外部使用来说却是一致的。

下面看看unordered_map使用例子

int main()
{
	
	//1.插入元素,和map用法一样,可以看看我之前的map文章。
	unordered_map<int, string> m_unorderdMap;
	m_unorderdMap.insert(make_pair(1, "jack1"));
	m_unorderdMap.insert(make_pair(3, "jack3"));
	m_unorderdMap.insert(make_pair(4, "jack4"));
	m_unorderdMap.insert(make_pair(2, "jack2"));
	m_unorderdMap.insert(make_pair(2, "jack2222"));//不会插入
	//2.遍历
	for (auto node :m_unorderdMap)
	{
		cout << node.first << "  " << node.second << endl;
	}

	//3.随机访问
	auto it = m_unorderdMap[5];
	cout << it.c_str() << endl;

	//再次遍历
	cout << "使用数组下标[]方式取一个没有的值后遍历:\n";
	for (auto node : m_unorderdMap)
	{
		cout << node.first << "  " << node.second << endl;
	}

	//4.判断是否有元素
	if (m_unorderdMap.empty())
	{
		cout << "m_unorderdMap 是空的!\n";
	}
	else
	{
		cout << "m_unorderdMap 不是空的!\n";
	}
	//5.查找1,count 如果个数不为0就说明找到了。
	int ncount = m_unorderdMap.count(1);
	cout << "1的个数:" << ncount << endl;

	ncount = m_unorderdMap.count(2);
	cout << "2的个数:" << ncount << endl;

	//6.查找2 find
	std::unordered_map<int,string >::iterator itx  = m_unorderdMap.find(2);
	if (itx !=  m_unorderdMap.end())
	{
		cout << "找到:"<<itx->first<<" " <<itx->second << endl;
	}
	cout << endl;

	system("pause");
	return 0;
}

结果:
STL-12-unordermap和map的不同_第1张图片
    从结果可以看出是没有顺序的,和map的性质一样,它不允许插入相同的元素。

注意:

    unordered_map, 它与 map的区别就是,map是按照operator<比较判断元素是否相同,以及比较元素的大小,然后选择合适的位置插入到树中。所以,如果对map进行遍历(中序遍历)的话,输出的结果是有序的。顺序就是按照operator< 定义的大小排序。

    而unordered_map是计算元素的Hash值,根据Hash值判断元素是否相同。所以,对unordered_map进行遍历,结果是无序的。

    用法的区别就是,map 的key需要定义operator< 。 而unordered_map需要定义hash_value函数并且重载operator==。对于内置类型,如string,这些都不用操心。对于自定义的类型做key,就需要自己重载operator< 或者hash_value()了。

如果key是自定义类型时,直接使用std::unordered_map,编译时会报错,错误信息为:”error C2338: The C++ Standard doesn’t provide a hash for this type.”大意是,C++标准库没有为该类型提供hash操作!因此,针对自定义类型,我们在使用std::unordered_map时必须提供自定义的Hash函数。

参考:https://blog.csdn.net/qq_21997625/article/details/84672775
参考:

你可能感兴趣的:(STL)