在前面的章节中,我们见过一些O(logN)级的查找算法,而本章我们讨论O(1)级的办法。
实现极速查找的奥秘在于把目标对象映射到一个数组中去,而每个对象在数组中的位置,则是根据对象的内容计算出来的。这种计算索引的函数称为Hash函数。
func Hash32(seed uint32, str string) uint32 {
code := seed
m := len(str) % 4
for i := 0; i < len(str)-m; i += 4 {
w := getU32(str[i:])
w *= 0xcc9e2d51
w = (w << 15) | (w >> 17)
w *= 0x1b873593
code ^= w
code = (code << 13) | (code >> 19)
code += (code << 2) + 0xe6546b64
}
if m != 0 {
w := uint32(0)
for i := len(str) - 1; i >= len(str)-m; i-- {
w = (w << 8) | uint32(str[i])
}
w *= 0xcc9e2d51
w = (w << 15) | (w >> 17)
w *= 0x1b873593
code ^= w
}
code ^= uint32(len(str))
code ^= code >> 16
code *= 0x85ebca6b
code ^= code >> 13
code *= 0xc2b2ae35
code ^= code >> 16
return code
}
Hash函数设法将如字符串之类的非整数内容转成一个整数,然后用此数和数组长度取模便可获得确定的落点。这种计算出来的落点可能会存在冲突,怎么解决这种冲突将是本章的核心议题。