map与unordered_map都是c++ stl中的关联容器,两者的使用也都大致相同。不过在底层的实现上,map使用的是红黑树,unordered_map使用的则是hash表。
红黑树
红黑树是一种相对平衡的二叉搜索树,并且其附加定义如下:
- 节点有且只有两种颜色,红色和黑色
- 根节点和叶子节点必须是黑色,其中,叶子节点是虚拟存在的空节点NULL
- 红色节点的两个子节点必须是黑色
- 任意节点到叶子节点的路径上,必须包含相同数目的黑色节点
可以参考一下以下blog:
Red-Black Trees
相对于AVL平衡树,红黑树对于平衡性的要求没有那么高,由于其对于颜色的定义,任意节点左右子树的高度差在一倍之内(最长路径为节点红黑相间,最短路径为节点全黑),因此频繁插入和删除节点时,触发平衡调整的次数更少,平衡调整的过程也更易收敛。
而c++ stl中的map使用红黑树作为底层实现,对于map中的键值,它只要能够比较大小:如数值、字符串或其它能够支持大小比较的类就可以。
hash表
hash表,其实就是通过一定的算法:hash函数将原始数据转为一段固定长度的数值(表这个词其实没有具体意义,hash的存储方式有很多,如再链表法,如开放地址法的数据结构,表只是对于它们的一种笼统称呼)。
具体可见:什么是hash
这里主要回答一下我自己长期的一个误区:
即之前我一直以为hash只适用于key-value这样的数据,并且认为hash表中只存储value,那么根据key的hash值寻找数据时,存在hash冲突的话,就没法知道当前hash值对应的value数据到底哪个是对应于key的。
其实,hash也可以对于不是key-value这样的数据进行存储,比如就是一系列大量的数值或字符串,我们可以使用hash算法,而不是简单的数组顺序存储,为的是加快查找速度;并且对于key-value这样的数据,其实hash表中所存储的不是只有value,而是key-value这个键值对都存储了,这样在有hash冲突的情况下就能根据key值找到真正对应的value。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。