STL源码:hashtable
2015-03-31 16:52
225 查看
前面介绍的RB-tree红黑树中,可以看出红黑树的插入、查找、删除的平均时间复杂度为O(nlogn)。但这是基于一个假设:输入数据具有随机性。而哈希表/散列表hash table在插入、删除、查找上具有“平均常数时间复杂度”O(1);且不依赖输入数据的随机性。
hash函数会带来一个问题:可能有不同的元素被映射到相同位置,这就是碰撞问题。解决碰撞的方法很多,hash table的实现有线性探测、二次探测、二次散列等实现,SGI的STL是采用开链法(separate chaining)来实现的。大概原理就是在hash table的每一项都是个指针(指向一个链表list),叫做bucket。这样的话如果多个key值散列到同一位置,那么就存储到这个位置对应的链表中。list执行元素插入、搜索、删除等操作,虽然list进行搜索时是线性操作,但是list足够短的话,速度还是很快。结构如下。
注意:bucket维护的linked list不是STL的list或slist,而是自己维护的hash table node。buckets聚合体,则以vector完成,以便于动态扩充。vector容器大小是质数(因为散列函数好多情况下是取余数)。
hash table的节点定义:
hash函数
hash函数时用于计算元素位置的函数,SGI将这项任务赋予bkt_num(),再由它来调用hash函数,取得一个可以对hashtable进行模运算的值。对于char,int, long等整型数据,hash函数什么也没做,只是忠诚地返回原值。但对于字符串(const char *),设计了转型函数,见下图。<stl_hash_fun.h>定义了数个现成的hash函数。
SGI所定义的所有hash函数如下图,SGI hashtable无法处理其他类型的元素,例如string,double,float等,若要处理这些类别,用户必须自己定义hash函数。
现在这个说法是不正确的,因为标准库已经增加了很多类型hash的支持,因此不限于上边说的那些了,详情看最后一幅图或参考http://en.cppreference.com/w/cpp/utility/hash
目前C++标准库支持hash函数的元素类型:
hash函数会带来一个问题:可能有不同的元素被映射到相同位置,这就是碰撞问题。解决碰撞的方法很多,hash table的实现有线性探测、二次探测、二次散列等实现,SGI的STL是采用开链法(separate chaining)来实现的。大概原理就是在hash table的每一项都是个指针(指向一个链表list),叫做bucket。这样的话如果多个key值散列到同一位置,那么就存储到这个位置对应的链表中。list执行元素插入、搜索、删除等操作,虽然list进行搜索时是线性操作,但是list足够短的话,速度还是很快。结构如下。
注意:bucket维护的linked list不是STL的list或slist,而是自己维护的hash table node。buckets聚合体,则以vector完成,以便于动态扩充。vector容器大小是质数(因为散列函数好多情况下是取余数)。
hash table的节点定义:
template <class Value> struct __hashtable_node { __hashtable_node* next; Value val; };
hash函数
hash函数时用于计算元素位置的函数,SGI将这项任务赋予bkt_num(),再由它来调用hash函数,取得一个可以对hashtable进行模运算的值。对于char,int, long等整型数据,hash函数什么也没做,只是忠诚地返回原值。但对于字符串(const char *),设计了转型函数,见下图。<stl_hash_fun.h>定义了数个现成的hash函数。
SGI所定义的所有hash函数如下图,SGI hashtable无法处理其他类型的元素,例如string,double,float等,若要处理这些类别,用户必须自己定义hash函数。
现在这个说法是不正确的,因为标准库已经增加了很多类型hash的支持,因此不限于上边说的那些了,详情看最后一幅图或参考http://en.cppreference.com/w/cpp/utility/hash
目前C++标准库支持hash函数的元素类型:
相关文章推荐
- STL之hashtable源码剖析
- SGISTL源码探究-STL中的hashtable(上)
- STL源码阅读-hashtable
- STL源码分析之hashtable
- SGISTL源码探究-STL中的hashtable(下)
- Java 集合系列11之 Hashtable源码解析
- [源码解析]HashMap和HashTable的区别(源码分析解读)
- Hashtable 源码解析(基于JDK1.7)
- 转:【Java集合源码剖析】Hashtable源码剖析
- STL源码阅读(七)
- 源码]java合并两个文件,hashtable去重。
- STL 源码剖析 算法 stl_algo.h -- binary_search
- PHP源码分析之HashTable(2)
- STL源码分析之bitset源码分析
- 集合学习--HashTable 源码初探
- HashTable<k,v>源码解析
- SGISTL源码探究-stl_algobase.h中的算法
- C++ Standard Stl -- SGI STL源码学习笔记(03) STL中的模板编译期检查与偏特化编译期检查
- [转] STL源码学习----lower_bound和upper_bound算法
- STL源码解析 - sort