数据结构例程——哈希表及其运算的实现
本文是[数据结构基础系列(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.写出哈希表的基本概念 2.列出常用的哈希函数构造方法,并阐述各自的特点. 直接定址法 除留余数法 数字分析法 其他构造整数关键字的哈希函数的方法: 平方取中法 ...
- 用开放地址法中的线性探查法解决冲突实现哈希表的运算
为了更深的理解哈希算法,自己写了用开放地址法中的线性探查法解决冲突实现哈希表的运算. /*** Created by lirui on 14-8-13.* 用开放地址法中的线性探查法解决冲突实现哈希表 ...
- 用c语言实现基本数据结构(哈希表)
用c语言实现基本数据结构(哈希表) 写这个哈希表总是段错误,找了半天的bug...原来是各种小错误不断,写得很蛋疼. 我是是用数组实现的,数组的最大值定义成的宏.一共只有四个函数,分别为初始化哈希表, ...
- C++八股文分享---数据结构其二---哈希表
C++八股文分享-数据结构其二-哈希表 前言 什么是哈希表? 搜索二叉树对值的查找是通过从根节点开始,逐个节点与目标值做比较,向下查找,直至找到目标值或是到达根节点未查找到,时间复杂度为O(logn) ...
- 图书馆管理系统(C、数据结构、哈希表、文件IO)
目录 技术路线 实现效果展示 程序主体 1.头文件部分 2.自定义函数定义部分 3.main函数部分 注意 技术路线 数据结构.哈希表.文件IO 通过C语言进行程序设计,有用到数据结构中的哈希表,通 ...
- 「Redis数据结构」哈希表(Dict)
「Redis数据结构」哈希表(Dict) 文章目录 「Redis数据结构」哈希表(Dict) @[toc] 一.概述 二.结构 三.哈希冲突 四.链式哈希 五.rehash 六. 渐进式 rehash ...
- j - 数据结构实验:哈希表_一看就懂的数据结构基础「哈希表」
哈希表 哈希表(Hash table),是存储键值(Key Value)对数据的一种数据结构. 例如,我们可以将人的名字作为键,性别作为值来存储.通过把键映射到表中的一个位置来访问数据,以提高查找速度 ...
- 数据结构:哈希表函数构造和冲突解决方法
哈希表 哈希函数:记录的存储位置和它的关键字之间建立一个确定的对应关系. 冲突:对不同的关键字可能得到同一哈希地址,这种现象称为冲突. 哈希函数构造方法 1.直接定址法 取关键字或关键字的某个线性函数 ...
- 【数据结构】哈希表——线性探测法、链地址法、查找成功、查找不成功的平均长度
一.哈希表 1.概念 哈希表(Hash Table)也叫散列表,是根据关键码值(Key Value)而直接进行访问的数据结构.它通过把关键码值映射到哈希表中的一个位置来访问记录,以加快查找的速度.这个 ...
最新文章
- Android Service的绑定 基础概念篇
- 关键路径法及C语言实现
- Animation.wrapMode循环模式
- 大规模数据处理开源软件
- Android Studio:64K问题com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536
- 在python中操作excel
- 史上最全最常用批处理260多个打包下载
- 逻辑回归(Logistic Regression, LR)又称为逻辑回归分析,是分类和预测算法中的一种。通过历史数据的表现对未来结果发生的概率进行预测。例如,我们可以将购买的概率设置为因变量,将用户的
- 云钻还在吗 苏宁怎么解除实名认证_快手7天怎么养号,5步简易养号方案送上
- java泛型实验报告,java实验报告异常集合类和泛型
- 编程语言的好坏,没那么重要?
- Java基础复习---线程创建
- python程序设计——班级档案管理系统
- 《运营力——微信公众号 设计 策划 客服 管理 一册通》一一1.1 创博公众号团队简介...
- seq2seq发展介绍
- 技术状态管理(六)-技术状态审核
- 太吾绘卷第一世攻略_《太吾绘卷》怎么让自己子嗣兴旺 后宫养成子嗣兴旺方法攻略...
- python制作手机壁纸_用Python生成自己独一无二的手机壁纸
- 区块链学习名词详解-Part1
- 25个细致微妙的扁平化2.0风格网页设计