浅谈哈希表(HashTable)

概述

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。

哈希表是一种通过哈希函数将特定的键映射到特定值的一种数据结构,他维护者键和值之间一一对应关系。

  • 键(key):又称为关键字。唯一的标示要存储的数据,可以是数据本身或者数据的一部分。
  • 槽(slot/bucket):哈希表中用于保存数据的一个单元,也就是数据真正存放的容器。
  • 哈希函数(hash function):将键(key)映射(map)到数据应该存放的槽(slot)所在位置的函数。
  • 哈希冲突(hash collision):哈希函数将两个不同的键映射到同一个索引的情况。

这么讲真的太太太抽象了,我举个例子吧



Example1这里面的h函数即为哈希函数,由算法很容易知道为x对5取余数 h(47)明显为2
Example2中的函数同理

访问键值k

对于一个存储n个数据的哈希表,则哈希表中为HT[0]~HT[N-1],但我们对于访问的键值为2的槽,只需要使用HT[2]即可

Hash Fuction哈希函数

这个有很多,举几个经典的算法

int h1(int x){
  return (x%5);
}

int h2(char* x){
  int i,sum;
  for(sum=0, i=0; x[i] != '\0'; i++)
    sum += (int)x[i];
  return (sum%5);
}

int ELFhash(char*key)
{
    unsigned long h=0;
    while(*key)
    {
        h = (h << 4) + *key++;
        unsigned long g = h & 0xF0000000L;
        if(g)
            h ^= g >> 24;
        h &= ~g;
    }
    return h % MOD;
}

ELFhash这个字符串hash函数中涉及许多位运算,有兴趣的可以上网查查,这里就不详述了。

Hash Collision哈希冲突


显而易见,哈希冲突就是指不同的键值k1,k2在哈希函数h(x)映射下到了相同的slot
自然,有冲突就会有解决方案。

Open Hashing 拉链法

名词解释:叫拉链,是因为哈希冲突后,用链表去延展来解决。


这个图中h(x) = x mod 10 ;是一个哈希函数,可见代入x=91x=1的时候都会到映射到键值为1的slot,那么这样就会引发冲突,在拉链法中,用链表延展去存储同键值的数据。
优点

  1. 拉链法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短;
  2. 在用拉链法构造的散列表中,删除结点的操作易于实现

缺点
在对链表进行存储空间分配的时候,会降低整个程序的运行速率

Closed Hashing 开地址法 (Open Addressing)

名词解释:叫Closed,是因为哈希冲突后,并不会在本身之外开拓新的空间,而是继续顺延下去某个位置来存放,所以是一个密闭的空间,所以叫“Closed”,至于开地址(Open Addressing),这个应该相对于那种通过链表来开拓新空间,它是在本身地址上,另外找个位置。所以叫开地址。

以下介绍常用的开地址法

  1. Bucket Hashing哈希桶
  2. Probing 探测
Bucket Hashing 哈希桶

这一页PPT应该很好理解,采用的是哈希桶(Bucket Hashing),每个桶的大小为2,一共有5个桶,所以一共有5*2=10个槽(slot)
插入的算法很简单

  1. 把数据放到经过哈希函数后得到key值第一个slot里
  2. 若slot已经被占用,用下一个slot
  3. 如果bucket满了,把数据放到overflow里面

查找算法也很简单

  1. 先得到键值key
  2. 再在bucket中找第一个第二个
  3. 若找不到再在overflow中找
Probing探测

p(k,i)探测函数。其值为第i次探测时相对h(k)的便宜

Pos(i)=(h(k) + p(k ,i)) % M;


Linear Probing 线性探测

p(i) = i ;
p(i) = i * c ;

注意这里的c必须与表的大小M互质

但是线性探测有一个很明显的缺点,就是数据很可能会聚集在一块
Quadratic Probing 平方探测


例子

p(1)=1;
p(2)=4;
p(2)=9;
对于h(k1)=3
h(k1)+p(1)=h(k1)+1=4
h(k1)+p(2)=h(k1)+4=7
h(k1)+p(3)=h(k1)+9=12

Random Probing 随机探测

p(k,i) = random();

但是并不存在真随机,如果存在真随机,会出现slot无法被哈希函数搜索到
Pseudo-Random Probing 伪随机探测


看图中的
探测序列为r1,r2,r3...即

p(1)=r1;
p(2)=r2;
p(2)=r3;
对于h(k1)=30
h(k1)+p(1)=h(k1)+2=32
h(k1)+p(2)=h(k1)+5=35
h(k1)+p(3)=h(k1)+32=62

Double Hashing 双重散列
这是用于开放寻址法的最好方法之一,具有随机选择排列的许多特性



h2(k)的值必须要与表的大小M互质

删除

  1. Tombstones墓碑
  2. Local Reorganization
  3. Rehash

where $\mu$ is the mean value, $\sigma^2$ is standard deviation

参考

  • 百度百科
  • 哈希表概述
  • Open Hash
  • 算法导论第三版
  • 华工计算机科学与工程学院数据结构课程PPT
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容