哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。哈希表在像Java、C#等语言中是与生俱来的。可是在C的世界中,似乎只有自己动手,丰衣足食了。

哈希表实现中需要注意的问题。

1. 哈希函数

也叫散列函数,即:根据key,计算出key对应记录的储存位置:position = f(key)

散列函数满足以下的条件:

  1. 对输入值运算,得到一个固定长度的摘要(Hash value);
  2. 不同的输入值可能对应同样的输出值;

以下的函数都可以认为是一个散列函数:

  • f(x) = x mod 16;
  • f(x) = (x2 + 10) * x;
  • f(x) = (x | 0×0000FFFF) XOR (x >> 16);

不过,仅仅满足上面这两条的函数,作为散列函数,还有不足的地方。我们还希望散列函数满足下面几点:

  1. 散列函数的输出值尽量接近均匀分布;
  2. x的微小变化可以使f(x)发生非常大的变化,即所谓“雪崩效应”(Avalanche effect);

上面两点用数学语言表示,就是:

  1. 输出值y的分布函数F(y)=y/m, m为散列函数的最大值。或记为y~U[0, m]
  2. |df(x)/dx| >> 1;
  • 从上面两点,大家看看,前面举例的三个散列函数,哪个更好呢?对了,是第三个:f(x) = (x | 0×0000FFFF) XOR (x >> 16);

它很完美地满足“好的散列函数”的两个附加条件。

2、哈希冲突(Hash collision)

也就是两个不同输入产生了相同输出值的情况。首先,哈希冲突是无法避免的,因此,哈希算法的选择直接决定了哈希冲突发送的概率;同时必须要对哈希冲突进行处理,方法主要有以下几种:

  1. 链地址法。即对Hash表中每个Hash值建立一个冲突表,即将冲突的几个记录以表的形式存储在其中。具体可以参照 散列冲突处理:链地址法 。
  2. 开放地址法。具体可以参照 散列冲突处理:开放定址法 。
//#include "stdafx.h"
#include "string.h"
#include "stdio.h"
#include "stdlib.h"typedef struct _node
{char *name;char *desc;struct _node *next;
} node;#define HASHSIZE 101
static node* hashtab[HASHSIZE];void inithashtab()
{int i;for(i=0; i < HASHSIZE; i++)hashtab[i]=NULL;
}unsigned int hash(char *s)
{unsigned int h=0;for(; *s; s++)h=*s+h*31;return h%HASHSIZE;
}node* lookup(char *n)
{unsigned int hi=hash(n);node* np=hashtab[hi];for(; np!=NULL; np=np->next){if(!strcmp(np->name,n))return np;}return NULL;
}char* m_strdup(char *o)
{int l=strlen(o)+1;char *ns=(char*)malloc(l*sizeof(char));strcpy(ns,o);if(ns==NULL)return NULL;elsereturn ns;
}char* get(char* name)
{node* n=lookup(name);if(n==NULL)return NULL;elsereturn n->desc;
}int install(char* name,char* desc)
{unsigned int hi;node* np;if((np=lookup(name))==NULL){hi=hash(name);np=(node*)malloc(sizeof(node));if(np==NULL)return 0;np->name=m_strdup(name);if(np->name==NULL) return 0;np->next=hashtab[hi];hashtab[hi]=np;}elsefree(np->desc);np->desc=m_strdup(desc);if(np->desc==NULL) return 0;return 1;
}/* A pretty useless but good debugging function,
which simply displays the hashtable in (key.value) pairs
*/
void displaytable()
{int i;node *t;for(i=0; i < HASHSIZE; i++){if(hashtab[i]==NULL)printf("()");else{t=hashtab[i];printf("(");for(; t!=NULL; t=t->next)printf("(%s.%s) ",t->name,t->desc);printf(".)");}}
}void cleanup()
{int i;node *np,*t;for(i=0; i < HASHSIZE; i++){if(hashtab[i]!=NULL){np=hashtab[i];while(np!=NULL){t=np->next;free(np->name);free(np->desc);free(np);np=t;}}}
}main()
{int i;char* names[]= {"name","address","phone","k101","k110"};char* descs[]= {"Sourav","Sinagor","26300788","Value1","Value2"};inithashtab();for(i=0; i < 5; i++)install(names[i],descs[i]);printf("Done");printf("If we didnt do anything wrong..""we should see %s\n",get("k110"));install("phone","9433120451");printf("Again if we go right, we have %s and %s",get("k101"),get("phone"));/*displaytable();*/cleanup();return 0;
}

(7)哈希表的链地址法实现相关推荐

  1. SWUST OJ 1012: 哈希表(链地址法处理冲突)

    1012: 哈希表(链地址法处理冲突) 题目描述 采用除留余数法(H(key)=key %n)建立长度为n的哈希表,处理冲突用链地址法.建立链表的时候采用尾插法. 输入 第一行为哈西表的长度m: 第二 ...

  2. 数据结构---散列表(哈希表)链地址法

    散列表链地址法基本思想是将相同散列地址的元素放在同一个单链表中,即称同义词链表.例如此时我们设一个散列函数H(key)=key%n,则可以定义一个一维数组,大小为n,数组元素对应关键字模n所得的数字. ...

  3. 除留余数法构造哈希函数并用链地址法处理哈希冲突【C++实现】

    1.题目描述 哈希函数为H(key)=key%13,哈希冲突处理方法为:链地址法 c语言版数据结构上的例子 2.代码实现 首先建立一个哈希链表结点类HashNode,用于存放处理冲突时的关键字,其数据 ...

  4. 数据结构学习,哈希表(链地址)

    各位小伙伴,新年快乐. 哈希表,本质上是数组,而链地址就是存放了链表的数组. 借用哈希函数对某个数进行适当运算求得该数的哈希值,在根据这个哈希值对哈希表进行查找插入删除操作. 假设这是一个哈希表H,容 ...

  5. 7-45 航空公司VIP客户查询 【哈希表 链地址法】

    不少航空公司都会提供优惠的会员服务,当某顾客飞行里程累积达到一定数量后,可以使用里程积分直接兑换奖励机票或奖励升舱等服务.现给定某航空公司全体会员的飞行记录,要求实现根据身份证号码快速查询会员里程积分 ...

  6. 7-15 航空公司VIP客户查询 (25分)(没用stl,哈希链地址法实现)

    7-15 航空公司VIP客户查询 (25分) 不少航空公司都会提供优惠的会员服务,当某顾客飞行里程累积达到一定数量后,可以使用里程积分直接兑换奖励机票或奖励升舱等服务.现给定某航空公司全体会员的飞行记 ...

  7. 使用哈希函数:H(k)=3k MOD 11,并采用链地址法处理冲突。试对关键字序列(22,41,53,46,30,13,01,67)构造哈希表,求等概率情况下查找成功的查找长度,并设计构造哈希表

    使用哈希函数:H(k)=3k MOD 11 ,并采用链地址法处理冲突. 试对关键字序列(22,41,53,46,30,13,01,67)构造哈希表, 求等概率情况下查找成功的查找长度,并设计构造哈希表 ...

  8. 【数据结构】哈希表——线性探测法、链地址法、查找成功、查找不成功的平均长度

    一.哈希表 1.概念 哈希表(Hash Table)也叫散列表,是根据关键码值(Key Value)而直接进行访问的数据结构.它通过把关键码值映射到哈希表中的一个位置来访问记录,以加快查找的速度.这个 ...

  9. 哈希表:线性探测法和链地址法求查找成功与不成功的平均查找长度

    哈希表:线性探测法和链地址法求查找成功与不成功的平均查找长度 了解ASL的公式 线性探测法求ASL 链地址法求ASL 了解ASL的公式 查找成功时:ASL =1n\frac{1}{n}n1​ ∑i=1 ...

最新文章

  1. 单片机中的ROM,RAM和FLASH的作用
  2. 17.抢购(秒杀)业务的技术要点
  3. PHP获取页面执行时间的方法
  4. 数据结构与算法之“之”字型打印矩阵和矩阵中找数
  5. mvc ajax给control传值问题
  6. js计算浮点数出现小数;解决js计算小数问题;js数组相加出现小数;
  7. python concat_python-pd.concat()不合并在同一索引上
  8. 一个研究生毕业以后的人生规划(ZT)
  9. JAVA课设——俄罗斯方块
  10. 会声会影滤镜特效教程之气泡滤镜
  11. windTerm—Xshell、SercureCRT等替代品
  12. python将word文档转图片_如何将word文档转换为图片
  13. uni-app实现APP中打开第三方app
  14. ODl之VTN详解-VTN概述
  15. gta5 apk android,gta5apk
  16. MySQL索引(漂亮简洁的思维导图)
  17. 【阶段三】Python机器学习30篇:机器学习项目实战:智能推荐系统的基本原理与计算相似度的常用方法
  18. 快速提取Word文档中的所有图片
  19. 后台管理系统项目搭建
  20. 【图论】中国邮递员问题、平面图上最大割问题的多项式时间算法

热门文章

  1. hanlp加载预训练模型
  2. python安装与使用Ta-Lib,获取金融技术面特征
  3. abaqus质量缩放系数取值_ABAQUS-延性损伤模型模拟金属材料断裂
  4. HDU 3359 高斯消元模板题,
  5. [转]OC与JS的交互详解
  6. EASYUI- EASYUI左移右移 GRID中值
  7. android中利用实现二级联动的效果
  8. C#中的文件流和文本流
  9. Zend Framework学习之Zend_Config
  10. python学习笔记全过程_Python学习笔记一(Hello World)