(第13讲)哈希表的开放地址法中的线性探测
2016-07-13 16:27
441 查看
哈希表:也叫散列表(Hash table,),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数(哈希函数),存放记录的数组叫做散列表(哈希表)。
线性探测:是指如果经过哈希化得到的数组下标,其对应的位置不为空或者不是被删除状态,就继续查看下一个位置,一次这样。公式如下所示:
Hi=(H(key)+di) MOD m i=1,2,...,k(k<=m-1)其中m为表长,di为增量序列
如果di值可能为1,2,3,...m-1,称线性探测再散列。
packagecom.eleven;
publicclass HashTableApp {
public static void main(String[] args){
int size = 10;//哈希表长度
int num = 8;//哈希表中数据项个数
int rate = 10;//比率为10,
HashTable hashtable = new HashTable(size);
/*for(int i =0;i<num;i++){
int value =(int)( Math.random()*rate*size);//表示关键字范围是120
//根据关键字创建数据项对象
Data1 data = new Data1(value);
//再根据数据项对象,新增哈希表
hashtable.insert(data);
}*/
int arr[] = {79,38,49,18,29};
for(int i =0;i<arr.length;i++){
Data1 data = new Data1(arr[i]);
hashtable.insert(data);
}
hashtable.display();
int findkey = 29;//设置要查找的关键值
Data1 finddata = hashtable.find(findkey);
if(finddata!=null)
System.out.println("找到"+findkey);
else
System.out.println("没找到"+findkey);
//删除操作
int deletekey = 18;
Data1 deletedata = hashtable.delete(deletekey);
if(deletedata!=null)
System.out.println("已经删除"+deletekey);
else
System.out.println("该哈希表中不含"+deletekey);
hashtable.display();
}
}
//数据类
classData1{
private int data;
public Data1(int data){
this.data = data;
}
public int getData(){
return data;
}
}
//哈希表:增,删, 查,遍历
classHashTable{
//定义一个数组,存放带关键值的数据项;定义数组的长度;定义被删除的数据项
private Data1 hashArr[] ;
private int arrlength;
private Data1 deleteData;
//构造函数,初始化三个变量
public HashTable(int size){
arrlength = size;
hashArr = new Data1[arrlength];
deleteData = new Data1(-1);
}
//哈希函数:将要输入的关键字或者数据项转换成数组下标
public int HashFunc(int key){
return key%arrlength;
}
//判断哈希表是否满
public boolean isFull(){
int num =0;
while(hashArr[num]!=null&&num<arrlength){//直到hashArr为空
num = num+1;
}
if(num==arrlength)
return true;
else
return false;
}
//增:假设哈希表未满,通过要输入的数据项得到关键值,再将其哈希化,
//迭代查找哈希表中此下标为空或者此处是被删除项,如果此处不为空,则递增下标继续查找
//知道找到空的或者被删除的,新增
public void insert(Data1 value){
if(!isFull()){
int key =value.getData();
int arrIndex =HashFunc(key);//得到哈希化的数组下标
//寻找哈希表中空的或者被删除的项
while(hashArr[arrIndex]!=null&& hashArr[arrIndex].getData()!=-1){
++arrIndex;
arrIndex %=arrlength;
}
hashArr[arrIndex] =value;
}
}
//删:根据关键值删除对应的数据项
//先转化为数组下标,再得到数组此位置对应的数据项,然后查找,删除并返回
public Data1 delete(int key){
int arrIndex = HashFunc(key);
while(hashArr[arrIndex]!=null){
if(hashArr[arrIndex].getData()==key){
Data1 data= hashArr[arrIndex];
hashArr[arrIndex]= null;
returndata;
}
//如果当前为止没找到,继续找下一个
++arrIndex;
arrIndex %=arrlength;
}
return null;//没有找到,
}
//查找
public Data1 find(int key){
int arrIndex = HashFunc(key);
while(hashArr[arrIndex]!=null){
if(hashArr[arrIndex].getData()==key)
returnhashArr[arrIndex];
//当前位置没有找到,继续往下一个位置找
++arrIndex;
arrIndex %=arrlength;
}
return null;//没找到
}
//遍历
public void display(){
for(inti=0;i<arrlength;i++){
if(hashArr[i]!=null)
System.out.print(hashArr[i].getData()+"");
else
System.out.print("**");
}
System.out.println();
}
}
结果是:
49 18 29 ** ** ** ** ** 38 79
找到29
已经删除18
49 ** 29 ** ** ** ** ** 38 79
线性探测:是指如果经过哈希化得到的数组下标,其对应的位置不为空或者不是被删除状态,就继续查看下一个位置,一次这样。公式如下所示:
Hi=(H(key)+di) MOD m i=1,2,...,k(k<=m-1)其中m为表长,di为增量序列
如果di值可能为1,2,3,...m-1,称线性探测再散列。
packagecom.eleven;
publicclass HashTableApp {
public static void main(String[] args){
int size = 10;//哈希表长度
int num = 8;//哈希表中数据项个数
int rate = 10;//比率为10,
HashTable hashtable = new HashTable(size);
/*for(int i =0;i<num;i++){
int value =(int)( Math.random()*rate*size);//表示关键字范围是120
//根据关键字创建数据项对象
Data1 data = new Data1(value);
//再根据数据项对象,新增哈希表
hashtable.insert(data);
}*/
int arr[] = {79,38,49,18,29};
for(int i =0;i<arr.length;i++){
Data1 data = new Data1(arr[i]);
hashtable.insert(data);
}
hashtable.display();
int findkey = 29;//设置要查找的关键值
Data1 finddata = hashtable.find(findkey);
if(finddata!=null)
System.out.println("找到"+findkey);
else
System.out.println("没找到"+findkey);
//删除操作
int deletekey = 18;
Data1 deletedata = hashtable.delete(deletekey);
if(deletedata!=null)
System.out.println("已经删除"+deletekey);
else
System.out.println("该哈希表中不含"+deletekey);
hashtable.display();
}
}
//数据类
classData1{
private int data;
public Data1(int data){
this.data = data;
}
public int getData(){
return data;
}
}
//哈希表:增,删, 查,遍历
classHashTable{
//定义一个数组,存放带关键值的数据项;定义数组的长度;定义被删除的数据项
private Data1 hashArr[] ;
private int arrlength;
private Data1 deleteData;
//构造函数,初始化三个变量
public HashTable(int size){
arrlength = size;
hashArr = new Data1[arrlength];
deleteData = new Data1(-1);
}
//哈希函数:将要输入的关键字或者数据项转换成数组下标
public int HashFunc(int key){
return key%arrlength;
}
//判断哈希表是否满
public boolean isFull(){
int num =0;
while(hashArr[num]!=null&&num<arrlength){//直到hashArr为空
num = num+1;
}
if(num==arrlength)
return true;
else
return false;
}
//增:假设哈希表未满,通过要输入的数据项得到关键值,再将其哈希化,
//迭代查找哈希表中此下标为空或者此处是被删除项,如果此处不为空,则递增下标继续查找
//知道找到空的或者被删除的,新增
public void insert(Data1 value){
if(!isFull()){
int key =value.getData();
int arrIndex =HashFunc(key);//得到哈希化的数组下标
//寻找哈希表中空的或者被删除的项
while(hashArr[arrIndex]!=null&& hashArr[arrIndex].getData()!=-1){
++arrIndex;
arrIndex %=arrlength;
}
hashArr[arrIndex] =value;
}
}
//删:根据关键值删除对应的数据项
//先转化为数组下标,再得到数组此位置对应的数据项,然后查找,删除并返回
public Data1 delete(int key){
int arrIndex = HashFunc(key);
while(hashArr[arrIndex]!=null){
if(hashArr[arrIndex].getData()==key){
Data1 data= hashArr[arrIndex];
hashArr[arrIndex]= null;
returndata;
}
//如果当前为止没找到,继续找下一个
++arrIndex;
arrIndex %=arrlength;
}
return null;//没有找到,
}
//查找
public Data1 find(int key){
int arrIndex = HashFunc(key);
while(hashArr[arrIndex]!=null){
if(hashArr[arrIndex].getData()==key)
returnhashArr[arrIndex];
//当前位置没有找到,继续往下一个位置找
++arrIndex;
arrIndex %=arrlength;
}
return null;//没找到
}
//遍历
public void display(){
for(inti=0;i<arrlength;i++){
if(hashArr[i]!=null)
System.out.print(hashArr[i].getData()+"");
else
System.out.print("**");
}
System.out.println();
}
}
结果是:
49 18 29 ** ** ** ** ** 38 79
找到29
已经删除18
49 ** 29 ** ** ** ** ** 38 79
相关文章推荐
- Same-origin security policy
- 【iOS】网络操作与AFNetworking
- nginx如何设置自定义404页面
- UVa 10106 Product
- 自我介绍和决心书
- C# 委托、事件
- oracle日期函数2!
- 将博客搬至CSDN
- the service threw an unknown exception in SCOM 2012
- CocoaPods安装
- 部署FIM 2010 R2—1先决条件准备
- 部署FIM 2010 R2—2服务账号和其他准备
- 部署FIM 2010 R2—3安装FIM 2010 R2 Service and Portal
- 部署FIM 2010 R2—4安装FIM 2010 R2 Synchronization Service
- PowerPC的字节序问题
- 部署FIM 2010 R2—5配置Synchronization Service
- 部署FIM 2010 R2——6安装和配置PCNS
- Docker在Ubuntu的部署实践
- 部署FIM 2010 R2——7验证不同林之间相同用户名密码同步
- [点分治] LA 7148 LRIP