散列表面面观

引子

散列的概念应用很广泛,比如加密,散列表,几何散列等。而散列表更是日常工作中常见的数据结构,同时也是面试中最常见的面试话题之一,很多问题都可以归结到散列表。网上的大部分文章都是直接进入hashMap的源码解读上,这会让很多刚开始接触散列表的童鞋觉得如坠雾里,看的不知所以。我认为这是因为对于散列的最基本的概念不熟悉导致的,所以这篇文章立足于散列的基本概念,层层递进讲解散列表,目的是让不了解散列的同学读完这篇文章也能较为深入了解散列表。

什么是散列表

提到散列表,关键的三个概念是键(key)、散列函数(hash Fuction)、散列表(hash Table)。通过wiki的解释我们可以加深理解散列表是根据键(key)直接访问内存存储位置的数据结构。即通过调用一个散列函数(形如F(key))来得到实际存放位置(散列表)来访问记录还有一个实际的例子:查找电话簿中某人号码,在首字母为W的表中查找“王”姓的电话号码,显然比直接查找就要快得多。这里使用人名作为关键字,“取首字母”是这个例子中散列函数的函数法则 F(),存放首字母的表对应散列表。我们可以通过下图简单的模型更加形象的了解散列表。

为什么会有散列

hash的概念起源于1956年,dumey用它来解决符号表问题。使得数据表的插入、删除、查询操作都可以在常数时间完成。我们常用的arrayList、linkedList一个善于查询、一个善于新增和删除,而散列表完美的将两者的长处集合,通过一层散列函数将数据的增删改查都维持在常数时间,正是这种长处让散列如此迷人。

散列深入

接下来我们更加深入的了解散列的内容

散列函数

我们知道散列函数就是通过key找到对应值的函数。作为一个散列函数,唯一的职责就是将key散列到散列表对应的位置上,从而找到记录。那么一个好的散列函数应该是保证对于每个key都均匀的对应到散列表的位置上,而不是每次都对应一个位置,或者某些位置对应次数明显多于其他,这是非常重要的。因为散列函数越好,那么出现散列冲突(见下面散列冲突)的次数就越少,从而间接提高了整个散列表的效率。

散列冲突

所谓散列冲突,就是多个key通过散列函数散列之后对应同一个地址。出现散列冲突之后我们要进行冲突的处理。通常使用的散列冲突处理方法有两种。一种是分离链接法(拉链法),另外一种是开放定址法(探测散列)。下面通过简单的散列函数(除留余数)来简单的介绍这两种方法。

  • 分离链接: 当遇到散列冲突时,使用链表解决,将冲突的key放到原来数据节点后面,形成链表数据结构。我们经常使用的hashmap使用的就是分离链接处理散列冲突。如下图所示

  • 开放定址:遇到散列冲突,一次尝试余下的单元,直到有空单元。如下图

装填因子

装填因子一般用λ表示,意义为散列表中的元素个数与该表大小的比。如果比例超过了装填因子,那么散列表会扩容,然后将原本的数据重新散列到新的散列表里,这个过程称之为rehash(再散列)。

  • 越大越好?:一般散列表会设置装填因子,理想的装填因子当然是1,即填满散列表,但是实际上并不是如此。因为装填因子越大意味着发生散列冲突的概率越大,而散列冲突对散列表的效率有影响。这一点不难理解,因为散列的是否发生多少冲突,那么查询修改删除的时候也会遇到同样次数的冲突,次数越多散列表的效率越低,所以装填因子不是越大越好而是选择合适的值。

  • 应该多大:不同的散列冲突方法采用的装填因子是不同的。比如分离链接采用的装填因子一般是0.7到0.8,开放定址一般是小于0.5(hashmap默认的装填因子为0.75)。这是因为分离连接采用的是链表解决冲突,如果冲突就加到链表里,这步动作是常数时间不论发生多少次冲突,而对于开放定址遇到冲突会继续寻找空单元,如果装填因子太大,那么冲突次数会增多,影响效率。所以分离连接的装填因子比开放定址的要大一些。

结语

本文对散列表的起源,基本的概念做了初步的介绍。理解这些散列表的概念能够帮助我们在平常使用散列表相关的比如hashmap等做到心中有数,同时对理解hashmap的实现也有很大的帮助。篇幅所限,关于散列表更加细致的内容此处没有详细讲解,但是相信度过的童鞋对于散列表也应该有了初步的理解,后续会深入研究java中用到散列的集合类,从而更加深入的理解散列表。

参考资料

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

推荐阅读更多精彩内容