1、hash的翻译为‘散列’,可以理解为使用对应hash算法,将任意数据转换为一个索引(散列值),直接使用这个索引所指向的地址。
2、hash算法:即将数据转化为索引的函数,func(data)= key,常见的算法如MD5、SHA1等。基本原理就是把任意长度的输入,通过Hash算法变成固定长度的输出。这个映射的规则就是对应的Hash算法,而原始数据映射后的二进制串就是哈希值。
- hash算法应该尽可能的避免冲突
- 从hash值不可以反向推导出原始的数据
- 输入数据的微小变化会得到完全不同的hash值,相同的数据会得到相同的值
- 哈希算法的执行效率要高效,长的文本也能快速地计算出哈希值
3、hash冲突:不同的data使用hash算法后,得到了相同的索引,即产生了hash冲突(或碰撞)。
在使用hash时,需要采用不同的方法来解决冲突。
4、c++中的散列表
数据结构:
struct node {
void *key;
void *val;
struct node *next;
};
链表法是常用的处理冲突的方式。通过引用链表来处理hash冲突,即将冲突元素用链表链接起来。 但过长的链表也会导致查找效率下降,在链表达到一定长度时,hash存储会转换为红黑树结构,将时间复杂度由O(n)变为O(log2n) 。扩容、缩容后都需要重新hash,即重新映射
hash_set是以hashtable为底层机制实现的。故对hash_set的各种操作可以转调用hashtable来实现。
hash_set与set的不同:hash_set的底层机制是hashtable,而set的底层机制是RB-tree;set的元素能够自动排序,而hash_set的元素没有排序功能
hash_set中键值就是实值,实值就是键值。
hash_multiset的与hash_set有很大的相同性,其唯一差别就是hash_multiset中的元素可以重复。hash_set中的插入函数使用的是hashtable中的insert_unique(),而hash_multiset中的插入函数使用的是hashtable中的insert_equal()。