跳跃表&hash

汇编刚学跳跃表,发现跳跃表与hash有着数不清的关系

维基百科:

哈希表哈希映射)是实现关联数组抽象数据类型数据结构,该结构可以将映射到。哈希表使用哈希函数来计算阵列的索引,从中可以找到所需的值。

理想情况下,散列函数会将每个密钥分配给一个唯一的存储桶,但大多数散列表设计采用不完美的散列函数,这可能会导致散列冲突,其中散列函数为多个密钥生成相同的索引。必须以某种方式适应这种碰撞。

在尺寸合适的哈希表中,每次查找的平均成本(指令数)与表中存储的元素数无关。许多哈希表设计还允许键值对的任意插入和删除,在(摊销[2])每个操作的恒定平均成本。[3] [4]

在许多情况下,哈希表平均比搜索树或任何其他查找结构更有效。因此,它们被广泛用于多种计算机软件中,特别是用于关联数组数据库索引高速缓存集合

 

处理跳跃表,哈希表是一个实现方式,哈希表是根据关键字(Key value)而直接访问在内存存储位置的数据结构。也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做散列函数,存放记录的数组称做哈希表,也叫散列表。

哈希是大数据技术的基础,大家应该都有了解了,这里就不深度展开了,算法导论有一章已经讲得非常清楚了,这里说说我觉得比较有意思的一个哈希的东西。

哈希表的核心是哈希算法,一个好的哈希算法可以让碰撞产生得更少,查找速度越接近于O(1),所以一个好的哈希算法非常重要。

哈希算法很多,说都说不完,不同的算法适应不同的场景,我知道的,传说中有一个哈希算法,来自魔兽世界(!!!!为了部落!!!!),号称暴雪哈希,该算法产生的哈希值完全无法预测,被称为"One-Way Hash"( A one-way hash is a an algorithm that is constructed in such a way that deriving the original string (set of strings, actually) is virtually impossible)。

// 初始化hash计算需要的基础map table
func initCryptTable() {
    var seed, index1, index2 uint64 = 0x00100001, 0, 0
    i := 0
    for index1 = 0; index1 < 0x100; index1 += 1 {
        for index2, i = index1, 0; i < 5; index2 += 0x100 {
            seed = (seed*125 + 3) % 0x2aaaab
            temp1 := (seed & 0xffff) << 0x10
            seed = (seed*125 + 3) % 0x2aaaab
            temp2 := seed & 0xffff
            cryptTable[index2] = temp1 | temp2
            i += 1
        }
    }
}

// hash, 以及相关校验hash值
func HashKey(lpszString string, dwHashType int) uint64 {
    i, ch := 0, 0
    var seed1, seed2 uint64 = 0x7FED7FED, 0xEEEEEEEE
    var key uint8
    strLen := len(lpszString)
    for i < strLen {
        key = lpszString[i]
        ch = int(toUpper(rune(key)))
        i += 1
        seed1 = cryptTable[(dwHashType<<8)+ch] ^ (seed1 + seed2)
        seed2 = uint64(ch) + seed1 + seed2 + (seed2 << 5) + 3
    }
    return uint64(seed1)
}
跳表的平均时间复杂度为O(logN) ,虽然有点迷。。
原文地址:https://www.cnblogs.com/lanclot-/p/10929753.html