根据数据元素的关键字和哈希函数建立哈希表并初始化哈希表,用开放定址法处理冲突,按屏幕输出的功能表选择所需的功能实现用哈希表对数据元素的插入,显示,查找,删除。
初始化哈希表时把elem[MAXSIZE]、elemflag[MAXSIZE]和count分别置0。创建哈希表时按哈希函数创建哈希表,输入数据元素的关键字时,以“0”结束输入且要求关键字为正整数,数据元素个数不允许超过表长MAXSIZE。
输出的形式:根据所选择的哈希表的功能输出相应提示语句和正确结果。
程序的功能:将一组个数不超过哈希表长度的数据元素,按其关键字和哈希函数存入哈希表中,如果产生冲突用开放定址法处理并找出相应的地址。能实现用哈希表对数据元素的插入,显示,查找,删除。
测试数据:maxsize=10
哈希函数:H(key)=key%7
处理冲突方法:开放定址法 Hi=(H(key)+di)%13 i=1,2,3,…,9
哈希表又称散列表。哈希表存储的基本思想是:以数据表中的每个记录的关键字 k为自变量,通过一种函数H(k)计算出函数值。把这个值解释为一块连续存储空间(即数组空间)的单元地址(即下标),将该记录存储到这个单元中。在此称该函数H为哈希函数或散列函数。按这种方法建立的表称为哈希表或散列表。
处理冲突的方法:
开放寻址法:Hi=(H(key) + di) MOD m, i=1,2,…, k(k<=m-1),其中H(key)为散列函数,m为散列表长,di为增量序列,可有下列三种取法:
1.di=1,2,3,…, m-1,称线性探测再散列;
2.di=1^2, (-1)^2, 2^2,(-2)^2, (3)^2, …, ±(k)^2,(k<=m/2)称二次探测再散列;
3.di=伪随机数序列,称伪随机探测再散列。
再散列法:Hi=RHi(key), i=1,2,…,k. RHi均是不同的散列函数,即在同义词产生地址冲突时计算另一个散列函数地址,直到冲突不再发生,这种方法不易产生“聚集”,但增加了计算时间;
链地址法(拉链法):将所有关键字为同义词的记录存储在同一线性链表中;
建立一个公共溢出区。
#include <iostream>
using namespace std;
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 10
#define SUCCESS 1
#define UNSUCCESS 0
typedef struct
{ int elem[MAXSIZE];
int elemflag[MAXSIZE];
int count;
}HashTable;
void InitialHash(HashTable &H)/*哈希表初始化*/
{ int i;
H.count=0;
for(i=0;i<MAXSIZE;i++)
{ H.elem[i]=0;
H.elemflag[i]=0;
}
}
int Hash(int kn) /*哈希函数H(key)=key MOD 7*/
{ return (kn%7);
}
int SearchHash(HashTable &H,int k) /*查找关键字为k的元素*/
{ int t,s;
s=t=Hash(k);
xun: if(H.elem[t]==k&&H.elemflag[t]==1) return SUCCESS;
else if(H.elem[t]!=k&&H.elemflag[t]==1)
{ t=(t+1)%MAXSIZE;
goto xun;
}
else return UNSUCCESS;
}
int InsertHash(HashTable &H,int e)/*插入元素e*/
{ int p;
p=Hash(e);
if(SearchHash(H,e) )
{ cout<<"已有此数!"<<endl;
return UNSUCCESS;
}
else
{ H.elemflag[p]=1;
H.elem[p]=e;
H.count++;
return SUCCESS;
}
}
void CreateHash(HashTable &H)/*创建哈希表*/
{ int s;
int e;
cout<<"请输入哈希表:(输入0结束!)"<<endl;
cin>>e;
while(e)
{ s=InsertHash(H,e);
if(!s)
{ cout<<"此数已存在!";
cin>>e;
}
else
cin>>e;
}
}
void PrintHash(HashTable H) /*显示元素及其位置*/
{ cout<<"哈希表地址:";
int i;
for(i=0;i<MAXSIZE;i++)
cout<<i<<" ";
cout<<endl<<"关键字: ";
for(i=0;i<MAXSIZE;i++)
cout<<H.elem[i]<<" ";
cout<<endl<<"关键字标志:";
for(i=0;i<MAXSIZE;i++)
cout<<H.elemflag[i]<<" ";
}
int DeleteHash(HashTable &H,int e) /*删除元素e*/
{ int i;
int a=0;
for(i=0;i<MAXSIZE;i++)
if(H.elem[i]==e&&H.elemflag[i]==1)
{ H.elemflag[i]=2;
H.count--;
H.elem[i]=0;
a++;
return SUCCESS;
}
if(!a)
{ cout<<"无此数!"<<endl;
return 0;//return UNSUCCESS;
}
return 0;
}
void main()
{ HashTable H;
int m,k,p;
int R;
do{cout<<endl<<"\t\t******************请选择功能********************"<<endl;
cout<<"\t\t\t1.初始化哈希表"<<endl<<"\t\t\t2.创建哈希表"<<endl<<"\t\t\t3.查找"
<<endl<<"\t\t\t4.插入"<<endl<<"\t\t\t5.删除"<<endl<<"\t\t\t6.输出哈希表:"<<endl<<"\t\t\t0.退出"<<endl;
cout<<"\t\t************************************************"<<endl;
cin>>m;
switch(m)
{ case 1: InitialHash(H);break;
case 2: CreateHash(H);break;
case 3: cout<<endl<<"请输入要查找的关键字:";
cin>>k;
p=SearchHash(H,k);
if(p) cout<<"查找成功!"<<endl;
else cout<<"查找失败!"<<endl;
break;
case 4: cout<<endl<<"请输入要插入的关键字:";
cin>>R;
p=InsertHash(H,R);
if(p) cout<<"插入成功!"<<endl;
else cout<<"插入失败!"<<endl;
break;
case 5: cout<<"请输出要删除的关键字:";
cin>>R;
p=DeleteHash(H,R);
if(p) cout<<"删除成功!"<<endl;
else cout<<"删除失败!"<<endl;
break;
case 6: PrintHash(H);break;
case 0: break;
default: cout<<endl<<"选择错误!";break;
}
}while(m!=0);
}
线性探测再散列 建立HASH表的更多相关文章
-
哈希表---线性探测再散列(hash)
//哈希表---线性探测再散列 #include <iostream> #include <string> #include <stdio.h> #include ...
-
DS哈希查找--线性探测再散列
题目描述 定义哈希函数为H(key) = key%11.输入表长(大于.等于11),输入关键字集合,用线性探测再散列构建哈希表,并查找给定关键字. --程序要求-- 若使用C++只能include一个 ...
-
哈希查找解决地址冲突的两种最常见方法(线性探测再散列,链地址法)C++实现
#include<iostream>#include<iomanip>using namespace std; typedef struct Node{ int data; s ...
-
JDK8;HashMap:再散列解决hash冲突 ,源码分析和分析思路
JDK8中的HashMap相对JDK7中的HashMap做了些优化. 接下来先通过官方的英文注释探究新HashMap的散列怎么实现 先不给源码,因为直接看源码肯定会晕,那么我们先从简单的概念先讲起 ...
-
哈希表(散列表)—Hash表解决地址冲突 C语言实现
哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.具体的介绍网上有很详 ...
-
Python与数据结构[4] ->; 散列表[2] ->; 开放定址法与再散列的 Python 实现
开放定址散列法和再散列 目录 开放定址法 再散列 代码实现 1 开放定址散列法 前面利用分离链接法解决了散列表插入冲突的问题,而除了分离链接法外,还可以使用开放定址法来解决散列表的冲突问题. 开放定 ...
-
《数据结构与算法分析——C语言描述》ADT实现(NO.05) : 散列(Hash)
散列(Hash)是一种以常数复杂度实现查找功能的数据结构.它将一个关键词Key,通过某种映射(哈希函数)转化成索引值直接定位到相应位置. 实现散列有两个关键,一是哈希函数的选择,二是冲突的处理. 对于 ...
-
oracle的散列聚簇表
在簇表中,Oracle使用存储在索引中的键值来定位表中的行, 而在散列聚簇表中,使用了散列函数代替了簇索引,先通过内部函数或者自定义的函数进行散列计算,然后再将计算得到的码值用于定位表中的行. 创建散 ...
-
Redis数据类型之散列类型hash
在redis中用的最多的就是hash和string类型. 问题 假设有User对象以JSON序列化的形式存储到redis中, User对象有id.username.password.age.name等 ...
随机推荐
-
Openfire/XMPP学习之——一个简单的Smack样例
昨天讲了Openfire的搭建和配置,今天来讲一下Smack.如果对如何搭建和配置Openfire的,可以参考Openfire/XMPP学习之——Openfire的安装.配置. Smack是一个开源, ...
-
exp导出做成批处理注意事项
不能叫exp.bat,会一直显示导出这句话. 出现EXP-00106: 数据库链接口令无效:是因为http://blog.csdn.net/hzfu007/article/details/189823 ...
-
使用cookie实现打印浏览记录的功能
可以用cookie知识来实现打印浏览记录.这里面用到的思路是将浏览记录以字符串的方式保存到cookie中,当浏览记录增加时,再将其转化为数组. $uri=$_SERVER['REQUEST_URI'] ...
-
HBase集群搭建
HBase集群搭建 搭建环境:假设我们的linux环境已经准备好,包括网络.JDK.防火墙.主机名.免密登录等都没有问题,而且一定要有zookeeper.下面我们用3台linux虚拟机来搭建Hbase ...
-
HDU 2669 Romantic(扩展欧几里德, 数学题)
题目 //第一眼看题目觉得好熟悉,但是还是没想起来//洪湖来写不出来去看了解题报告,发现是裸的 扩展欧几里得 - - /* //扩展欧几里得算法(求 ax+by=gcd )//返回d=gcd(a,b) ...
-
Python 列表实现字典的get功能
字典有一个很好用的方法,就是get,既可以预防KeyError异常,也可以为不存在的key设置一个默认的value 例如: v=d.get('k','default') 而列表没有一个类似的方法,如果 ...
-
android四大组件详解--摘
Android四大基本组件介绍与生命周期 Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器 ...
-
nginx做反向负载均衡,后端服务器获取真实客户端ip(转)
首先,在前端nginx上需要做如下配置: location / proxy_set_hearder host $host; proxy_set_header X-forw ...
-
python-冒泡排序,升序、降序
冒泡排序 这个算法的名字由来是因为越大的元素会经交换慢慢浮'到数列的顶端. 冒泡排序的基本思想:重复走访要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来,直到没有再需要交换,完成排序 ...
-
shiro架构
1 shiro介绍 1.1 什么是shiro 分享牛系列,分享牛专栏,分享牛.shiro是apache旗下一个开源框架,它将软件系统的安全认证相关的功能抽取出来,实现用户身份认证,权限授权.加密.会 ...