(1)hash是一种压缩映射,任何长度的数据都可以映射到等长的字符串;
(2)hash是一种散列算法,原数据有微小改动时,输出数据会有巨大的改变;
(3)同一种算法,同一原数据,不同时空,会输出相同的数据;
(4)hash存在数据碰撞,10x10的二维空间,有100个点映射到该空间内,(1,2)(8,9)可能都映射到(3,4),称之为碰撞,但碰撞概率异常低;
hash的第一种用法:利用(1)、(2)来对数据签名,验证数据没有被修改:
hash的第二种用法:基于碰撞概率异常低,可以认为是一种全新的数据映射关系,用来储存key-value数据,即hashTable
hashTable技术,需要解决问题:1.碰撞概率可预测(n个数据需要映射到怎样的空间)、2.出现碰撞时需重新映射
HashMap通常会用一个指针数组(假设为table[])来做分散所有的key,当一个key被加入时,会通过Hash算法通过key算出这个数组的下标i,然后就把这个<key, value>插到table[i]中,如果有两个不同的key被算在了同一个i,那么就叫冲突,又叫碰撞,这样会在table[i]上形成一个链表。
我们知道,如果table[]的尺寸很小,比如只有2个,如果要放进10个keys的话,那么碰撞非常频繁,于是一个O(1)的查找算法,就变成了链表遍历,性能变成了O(n),这是Hash表的缺陷。所以,Hash表的尺寸和容量非常的重要。一般来说,Hash表这个容器当有数据要插入时,都会检查容量有没有超过设定的thredhold,如果超过,需要增大Hash表的尺寸,但是这样一来,整个Hash表里的元素都需要被重算一遍。这叫rehash,这个成本相当的大。
链接:https://www.jianshu.com/p/93580534fdb3
QHash是利用hash中key-》value数据映射时,碰撞异常低的特性,实现全新的key-value的数据模型
QHash接口和QMap几乎一样,相比QMap
(1).QHash有更快的查询速度
(2).QHash需要更多的空间(减少碰撞增加空间)
(3).QHash有更多的不稳定性(碰撞的处理)
(4).QHash的key类型更多,如QPoint等
static uint qHash(const QPoint& key, uint seed) { QString val = QString("%1x%2").arg(key.x()).arg(key.y()); return qHash<QString>(val, seed); } /* ...*/ QHash<QPoint, int > pos_vector_hash;