dictionary 跟 map 其实是同一个东西,只是在不同场合叫法不同。dictionary 的中文是字典,map 在中文是映射,也有地图的意思。查字典,查地图,都是通过某个信息,去找到另一个信息。HashTable指的是实现方式。
一、Map、Dictionary、HashTable有哪些异同
dictionary 跟 map 其实是同一个东西,只是在不同场合叫法不同。
dictionary 的中文是字典,map 在中文是映射,也有地图的意思。查字典,查地图,都是通过某个信息,去找到另一个信息。比如通过单词的拼写找到单词的具体含义。
类比查字典过程,单词的拼写为 key, 单词的具体含义为 value。dictionary 就是通过key,找到value,有时也将 dictionary 说成是 key-value 结构。只要达到查找目的,都可以叫做 dictionary。具体怎么找,可以有不同实现。
比如,最简单是将 key,value 放在一起,线性排。
k1, k2, k3, k4, k4 ….
v1, v2, v3, v4, v5 ….
当需要从 key 找到对应的 value 时,就从头到尾遍历过去。依次判断 k1, k2, k3, k4 是不是等于key, 当等于的时候,就找到 key 的具体位置,从而也就找到了value。
但这样从头到尾遍历,速度就太慢了,时间复杂度为 O(N)。N为数据的大小。
为了快速从key找到value。dictionary(或者说map)的通常有两种实现方式。
- 二叉树
- 哈希(hash)表
二叉树查找的时间复杂度为 O(logN),哈希表的时间复杂度大致为 O(1)。二叉树也分红黑树,AVL树等。哈希表的速度很快,很多语言内置的 dictionary 都使用哈希表来实现,但它通常会浪费一些存储空间。这部分有兴趣去看数据结构的书。
hash_map其实就是使用hash表实现的map。注意,二叉树,哈希表仅仅是 dictionary的实现方式,不能说hash就等于dictionary,实现方式可以有多种多样。
比如上面线性存储的实现,可以调整一下。当数据都放进来之后,先根据 key 来排序,再使用二分查找,就可以很快速地从 key 找到 value, 这种实现简单快速,并省内存,有时会比 hash 的实现更好。适合于一些数据不会经常变动的情况。
C++ 11的标准库中有个unordered_map,就是采用哈希表使用的 map。在C++11之前,没有标准的哈希实现,很多第三方库实现了哈希字典,基本都叫做 hash_map, 并应用广泛。所以C++11的实现就不能叫hash_map了,因为会造成很多现存的程序名字冲突。哈希实现的字典是无序,也就取了个不算太好的名字,unordered_map。
延伸阅读:
二、完全二叉树判定
1>如果树为空,则直接返回错;
2>如果树不为空:层序遍历二叉树;
2.1>如果一个结点左右孩子都不为空,则pop该节点,将其左右孩子入队列;
2.1>如果遇到一个结点,左孩子为空,右孩子不为空,则该树一定不是完全二叉树;
2.2>如果遇到一个结点,左孩子不为空,右孩子为空;或者左右孩子都为空,且则该节点之后的队列中的结点都为叶子节点,该树才是完全二叉树,否则就不是完全二叉树。