Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数.
在做某游戏资源管理时采用了建立hash表来快速索引寻获目标纹理的地址,因为采用了<key,val>(<string,struct>)的结构来标识一个目标,所以想到将key直接转化为地址,到网上搜索了下,最为经典的字符串hash算法是ELFhash(hash的百科中有介绍)
inline unsigned int ELF_hash(wchar_t *name) { unsigned long h = 0, g; while(*name) { h = (h << 4) + *name++; if(g = h & 0xf0000000) h ^= g >> 24; h &= ~g; } return (h%65536); }
建立一个256x256大小的hash表
texlist *texlist_headp[256*256];
一是因为hash散列的效果,注定很少情况下会产生冲突(当然,产生冲突的概率依算法的效率而定),那么每个链表的元素将会十分少,遍历时间必然会大幅度减少;
二是因为hash的特点,产生冲突的key的差异必将非常大(例如: "abcd" 和 "这是一个key" ),key在长度和特征上必将具有很大差异,在遍历时的筛选速度会大为提高(例如本例的用string作为key,通常strcmp只需判断前两个字符就可以筛掉不是目标的项,如果还要更快的速度的话,可以len特征,例如<key,keylen,value>,遍历链表时先对比keylen的大小,如果相同再strcmp),这在某些领域上优势是十分巨大的.
例如有以下命名习惯的key组:
地图_草原 |
地图_森林 |
人物_路人1 |
人物_路人2 |
模型_a |
模型_b |