码迷,mamicode.com
首页 > 其他好文 > 详细

[BS]散列表 哈希表 Hash table

时间:2015-03-30 14:38:42      阅读:224      评论:0      收藏:0      [点我收藏+]

标签:

《第五章》 散 列

散列表的实现常常叫做散列hashing)。散列是一种用于以常数平均时间执行插入、删除和查找的技术。技术分享


关于散列有一个很重要的概念:散列函数。散列函数是散列的关键处之一,散列函数又是基于映射机制的一种对应关系(一般是多对一的关系)。


这章可以分为5个部分:一般想法,散列函数,分离链接法,开放定址法(可分为线性探测、平方探测、双散列)、再散列、可扩散列。

本文只写到前四节。即:一般想法,散列函数,分离链接法,开放定址法(可分为线性探测、平方探测、双散列)(技术分享


第五章第一节:一般想法

把散列表当做一个简单的数组(其实我们会知道,散列表的实质就是一个数组),将这个数组的大小记录为TableSize。这么一来,我们可以根据

数组对应的下标[ 0 , TableSize - 1 ]来为我们将要存入的元素分配存放位置。下图是一个简单的理想散列表: 

                                                                          技术分享

YCX 2011716001被散列到了 1 ;

LeiLei 2011716037被散列到了 4 ;

Tracy 2011716049被散列到了 6;

这就是散列的基本思想。如果元素很多(超过了10个),并且不改变数组的大小,那么肯定有散列数是重复的吧?那么如何存放这些重复的元素呢?

这就是散列中最棘手的问题之一“collision”(译为冲突)。在研究如何解决冲突的过程下,产生了几种解决办法:分离链接法,开放定址法。

在介绍这几个冲突解决办法之前我们先看一下什么是散列函数。

第五章第二节:散列函数

设Hash( X )为散列函数,像这些:Hash( X ) = X % TableSize  或者 Hash( X ) = (将所有字符的ACSII码相加) 

或更为复杂一点的 Hash( X ) = Key[ 0 ] + 27 * Key[ 1 ] + 729 * Key[ 2 ]。这几个函数依次将数组的“利用率”提高了。


第五章第三节:分离链接法

这节比较简单,与链表本质一样。(技术分享


第五章第三节:开放定地址法

分为 线性探测法、平方探测法,双散列。

与分离链接法的区别是:开放定地址法再产生冲突的时候采用的不是分离链接的机制,而是增加了一种我称之为探测函数的函数。你确定名字足够形象?()

线性探测法的探测函数(绿色的)是:

h( X ) = ( Hash( X ) + F( i ) ) % TableSize , F( i ) = i ; i=1,2,3,4... ,Hash( X ) = X % TableSize(散列函数)

探测函数是怎么发挥作用的呢?例如:我们要将关键字{ 89,18,49,58,69 }依次放入散列表,那么过程是这样的:

机制是这样的:在每个元素进入散列表之前,先调用散列函数( Hash( X ) = X % TableSize )来处理这个数,当遇到冲突的时候请探测函数前来解围。

89被送到Hash( X ),处理....Hash( 89 ) = 89 % 10 = 9;查看散列号9可用,所以将其放入9中,如图:

TableSize = 10
0  
1  
2  
3  
4  
5  
6  
7  
8  
9 89

18 被送到Hash( X ),处理....Hash( 18 ) = 18 % 10 = 8;查看散列号8可用,所以将其放入8中,如图:

0  
1  
2  
3  
4  
5  
6  
7  
8 18
9 89
49 被送到Hash( X ),处理....Hash( 49 ) = 49 % 10 = 9;查看散列号9可用,所以请求探测君前来,[],放开那个数,让我来!!!

49 被送到探测函数中,处理....h1 (49 ) = ( 9 + 1 ) % 10 = 0;查看散列号0,发现可用,49被送到了0处,如图:

0 49
1  
2  
3  
4  
5  
6  
7  
8 18
9 89
58被送到Hash( X ),处理....Hash( 58 ) = 58 % 10 = 8;查看散列号8可用,所以请求探测君前来,[],放开那个数,让我来!!!

58 被送到探测函数中,处理....h1 (58 ) = ( 8 +1 ) % 10 = 9;查看散列号9,发现不可用,探测君继续探测:

58 被送到探测函数中,处理....h2 (58 )= ( 8 +2 ) % 10 = 0;查看散列号0,发现不可用,探测君继续探测:

58 被送到探测函数中,处理....h3 (58 ) = ( 8 +3 ) % 10 = 1;查看散列号1,发现可用,58几经辗转终于有了着落1处,如图:

0 49
1 58
2  
3  
4  
5  
6  
7  
8 18
9 89

69被....这个就不说了吧?如果一切正常的话那么如图所示:

0 49
1 58
2 69
3  
4  
5  
6  
7  
8 18
9 89

那么平方探测法呢?同理,除了F( i )不一样,其余的分析过程都是一样一样的。不再赘述。技术分享

[BS]散列表 哈希表 Hash table

标签:

原文地址:http://blog.csdn.net/oimchuan/article/details/44749213

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!