最近申请加入学校的机器人足球实验室,被要求写一个hash_map容器类,接口与STL相似。键的数据类型为string,值类型可以为内置类型或自定义。
myHashMap说明文档
一、设计思想:
1 哈希函数的设计: 将字符串按照“按位加权”,然后对哈希表大小取模将其映射到表中。
2解决冲突:采用开链法,发生冲突时将其放到对应的链表中。
3减少冲突:哈希表的大小取素数。 当元素个数/哈希表大小 > 0.75 时,扩大哈希表的大小,重建哈希表。
二、接口:
接口基本按照STL map的标准,但没有实现迭代器。
1 myHashNode<T> * begin() const ;
2 myHashNode<T> * end( ) const ; //超出末端指针
4 unsigned long size() const ;//哈希表已有的元素的个数
5 T get( myHashNode<T> * cur) const; //返回cur指针所指的值
6 unsigned long hash_function( string str , unsigned long SIZE) ;// 作用:对字符串str 返回哈希函数值
7 void insert( string str, T value ) ; // 插入关键字为str,值为value的组
8 myHashNode<T>* find( string str ) ; //查找关键字为str的组,返回其指针 ,若查找不到则返回“超出末端”的指针
9 void erase( string str ) ; //删除关键字为str的组
10 void resize( ) ; //扩大哈希表的容量
11 bool empty( ) ;//判断哈希表是否为空
12 void clear( ) ; //清空哈希表的所有元素
13 T& operator[] ( string str ) ; //重载[]运算符 ,若[]中的key不存在,则在表中插入一个关键字为key的新元素(保持与 STL的接口一致)
使用方法时与STL中的map基本一致。
声明hash_map 可以使用:
myHashMap< int > imap ;
myHashMap< point > pmap ;
而对容器的赋值可以使用下标如下:
imap[ str ] = 8;
查找键值为str的元组的值可以使用:
myHashMap * cur = imap.find( str ) ;
判断表中是否含键值为str的元组可以使用:
if ( imap.find( str ) == imap.end( ) ) //条件成立表明表中不含键值为str的组
判断哈希表是否为空可以使用:
if( imap.empty( ) ) //条件成立表明哈希表为空
而清空哈希表可以使用:
imap.clear( )
三、测试
我实现的这个hash_map 的键值是string类型的,而对应的值可以使各种类型的。
我用程序产生了2万多组随机的测试数据(见test_1.txt和test_2.txt,test.cpp为测试程序)测试了对应值类型为 int 和自定义的class类型两种情况,感觉查找、插入、删除的速度实在太快了,完全感觉不到延迟。
参考资料:《STL源码剖析》 侯捷 华中科技大学出版社 2002年
"my_hash_map.h"源代码:
源代码、测试程序、测试数据下载:源代码与说明文档.rar