本文是[数据结构基础系列(8):查找]中第11课时[哈希表——散列结构]和第12课时[哈希表的运算]的例程。

#include <stdio.h>
#define MaxSize 100         //定义最大哈希表长度
#define NULLKEY -1          //定义空关键字值
#define DELKEY  -2          //定义被删关键字值
typedef int KeyType;        //关键字类型
typedef char * InfoType;    //其他数据类型
typedef struct
{KeyType key;            //关键字域InfoType data;          //其他数据域int count;          //探查次数域
} HashData;typedef HashData HashTable[MaxSize];        //哈希表类型void InsertHT(HashTable ha,int &n,KeyType k,int p)  //将关键字k插入到哈希表中
{int i,adr;adr=k % p;if (ha[adr].key==NULLKEY || ha[adr].key==DELKEY)    //x[j]可以直接放在哈希表中{ha[adr].key=k;ha[adr].count=1;}else                    //发生冲突时采用线性探查法解决冲突{i=1;                //i记录x[j]发生冲突的次数do{adr=(adr+1) % p;  //此处处理冲突,但有不妥之处。应该%m,但m在这一个系列的解答中,并未作为参数传递进来。见程序后面的讨论i++;}while (ha[adr].key!=NULLKEY && ha[adr].key!=DELKEY);ha[adr].key=k;ha[adr].count=i;}n++;
}
void CreateHT(HashTable ha,KeyType x[],int n,int m,int p)  //创建哈希表
{int i,n1=0;for (i=0; i<m; i++)         //哈希表置初值{ha[i].key=NULLKEY;ha[i].count=0;}for (i=0; i<n; i++)InsertHT(ha,n1,x[i],p);
}
int SearchHT(HashTable ha,int p,KeyType k)      //在哈希表中查找关键字k
{int i=0,adr;adr=k % p;while (ha[adr].key!=NULLKEY && ha[adr].key!=k){i++;                //采用线性探查法找下一个地址adr=(adr+1) % p;}if (ha[adr].key==k)     //查找成功return adr;else                    //查找失败return -1;
}
int DeleteHT(HashTable ha,int p,int k,int &n)   //删除哈希表中关键字k
{int adr;adr=SearchHT(ha,p,k);if (adr!=-1)        //在哈希表中找到该关键字{ha[adr].key=DELKEY;n--;            //哈希表长度减1return 1;}else                //在哈希表中未找到该关键字return 0;
}
void DispHT(HashTable ha,int n,int m)    //输出哈希表
{float avg=0;int i;printf(" 哈希表地址:\t");for (i=0; i<m; i++)printf(" %3d",i);printf(" \n");printf(" 哈希表关键字:\t");for (i=0; i<m; i++)if (ha[i].key==NULLKEY || ha[i].key==DELKEY)printf("    ");         //输出3个空格elseprintf(" %3d",ha[i].key);printf(" \n");printf(" 搜索次数:\t");for (i=0; i<m; i++)if (ha[i].key==NULLKEY || ha[i].key==DELKEY)printf("    ");         //输出3个空格elseprintf(" %3d",ha[i].count);printf(" \n");for (i=0; i<m; i++)if (ha[i].key!=NULLKEY && ha[i].key!=DELKEY)avg=avg+ha[i].count;avg=avg/n;printf(" 平均搜索长度ASL(%d)=%g\n",n,avg);
}
int main()
{int x[]= {16,74,60,43,54,90,46,31,29,88,77};int n=11,m=13,p=13,i,k=29;HashTable ha;CreateHT(ha,x,n,m,p);printf("\n");DispHT(ha,n,m);i=SearchHT(ha,p,k);if (i!=-1)printf(" ha[%d].key=%d\n",i,k);elseprintf(" 未找到%d\n",k);k=77;printf(" 删除关键字%d\n",k);DeleteHT(ha,p,k,n);DispHT(ha,n,m);i=SearchHT(ha,p,k);if (i!=-1)printf(" ha[%d].key=%d\n",i,k);elseprintf(" 未找到%d\n",k);printf(" 插入关键字%d\n",k);InsertHT(ha,n,k,p);DispHT(ha,n,m);printf("\n");return 0;
}

附:关于上面解法中存在的问题
  1. 运行上面的程序,结果为

  结果正确。

  2.改换问题要求。还是这一组数,但哈希函数改为h(k)=k%11,装填因子选0.8,于是存储单元m=11÷0.8=13。期望的结果是:

  修改main函数,实施测试。改动如下:

int main()
{int x[]= {16,74,60,43,54,90,46,31,29,88,77};int n=11,m=13,p=11,i,k=29;   //将p修改为11HashTable ha;CreateHT(ha,x,n,m,p);……
}

  但运行结果中建立的哈希表却是:

  从代码中找其原因。解决冲突中重新定址的adr=(adr+1)%p应该是adr=(adr+1)%m,应该以存储单元数m为依据,决定是否将下标返回到0。
  本文开头的课件截图中,也明确示出 di=(di−1+1) mod m 。相关的InsertHT函数和SearchHT函数中对应的代码,都应该改过。在修改中,存储单元数m也应该作为参数传递给相关的函数。
  感谢烟台大学计146-2班杨珺同学指出错误。本文讨论至此,暂不做修改。这可能更有利于读者从我的错误中得到提高。

数据结构例程——哈希表及其运算的实现相关推荐

  1. 【数据结构】哈希表的概念及应用

    [数据结构]哈希表的概念及应用 前言 1.写出哈希表的基本概念 2.列出常用的哈希函数构造方法,并阐述各自的特点. 直接定址法 除留余数法 数字分析法 其他构造整数关键字的哈希函数的方法: 平方取中法 ...

  2. 用开放地址法中的线性探查法解决冲突实现哈希表的运算

    为了更深的理解哈希算法,自己写了用开放地址法中的线性探查法解决冲突实现哈希表的运算. /*** Created by lirui on 14-8-13.* 用开放地址法中的线性探查法解决冲突实现哈希表 ...

  3. 用c语言实现基本数据结构(哈希表)

    用c语言实现基本数据结构(哈希表) 写这个哈希表总是段错误,找了半天的bug...原来是各种小错误不断,写得很蛋疼. 我是是用数组实现的,数组的最大值定义成的宏.一共只有四个函数,分别为初始化哈希表, ...

  4. C++八股文分享---数据结构其二---哈希表

    C++八股文分享-数据结构其二-哈希表 前言 什么是哈希表? 搜索二叉树对值的查找是通过从根节点开始,逐个节点与目标值做比较,向下查找,直至找到目标值或是到达根节点未查找到,时间复杂度为O(logn) ...

  5. 图书馆管理系统(C、数据结构、哈希表、文件IO)

    目录 技术路线 实现效果展示 ​程序主体 1.头文件部分 2.自定义函数定义部分 3.main函数部分 注意 技术路线 数据结构.哈希表.文件IO 通过C语言进行程序设计,有用到数据结构中的哈希表,通 ...

  6. 「Redis数据结构」哈希表(Dict)

    「Redis数据结构」哈希表(Dict) 文章目录 「Redis数据结构」哈希表(Dict) @[toc] 一.概述 二.结构 三.哈希冲突 四.链式哈希 五.rehash 六. 渐进式 rehash ...

  7. j - 数据结构实验:哈希表_一看就懂的数据结构基础「哈希表」

    哈希表 哈希表(Hash table),是存储键值(Key Value)对数据的一种数据结构. 例如,我们可以将人的名字作为键,性别作为值来存储.通过把键映射到表中的一个位置来访问数据,以提高查找速度 ...

  8. 数据结构:哈希表函数构造和冲突解决方法

    哈希表 哈希函数:记录的存储位置和它的关键字之间建立一个确定的对应关系. 冲突:对不同的关键字可能得到同一哈希地址,这种现象称为冲突. 哈希函数构造方法 1.直接定址法 取关键字或关键字的某个线性函数 ...

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

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

最新文章

  1. Android Service的绑定 基础概念篇
  2. 关键路径法及C语言实现
  3. Animation.wrapMode循环模式
  4. 大规模数据处理开源软件
  5. Android Studio:64K问题com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536
  6. 在python中操作excel
  7. 史上最全最常用批处理260多个打包下载
  8. 逻辑回归(Logistic Regression, LR)又称为逻辑回归分析,是分类和预测算法中的一种。通过历史数据的表现对未来结果发生的概率进行预测。例如,我们可以将购买的概率设置为因变量,将用户的
  9. 云钻还在吗 苏宁怎么解除实名认证_快手7天怎么养号,5步简易养号方案送上
  10. java泛型实验报告,java实验报告异常集合类和泛型
  11. 编程语言的好坏,没那么重要?
  12. Java基础复习---线程创建
  13. python程序设计——班级档案管理系统
  14. 《运营力——微信公众号 设计 策划 客服 管理 一册通》一一1.1 创博公众号团队简介...
  15. seq2seq发展介绍
  16. 技术状态管理(六)-技术状态审核
  17. 太吾绘卷第一世攻略_《太吾绘卷》怎么让自己子嗣兴旺 后宫养成子嗣兴旺方法攻略...
  18. python制作手机壁纸_用Python生成自己独一无二的手机壁纸
  19. 区块链学习名词详解-Part1
  20. 25个细致微妙的扁平化2.0风格网页设计

热门文章

  1. Mysql数据库常用分库和分表方式
  2. 一款猥琐的PHP后门分析
  3. 下一代微服务Service Mesh原理及实践
  4. 前端跨域请求get_解决前端跨域问题方案汇总
  5. k8s各类yaml文件
  6. 《Go语言程序设计》读书笔记(十)反射
  7. 【1】Docker概述
  8. Nginx常用配置清单
  9. 使用Quartz来实现动态定时任务
  10. Java虚拟机栈详解