在线性探测中,已填充单元的长度不断增加,称为首次聚集,这会降低哈希表的性能,二次探测可以消除首次聚集。
Hi=(H(key)+di) MOD m i=1,2,...,k(k<=m-1)其中m为表长,di为增量序列
如果di值可能为1,2的平方,3的平方,...,称二次探测再散列。
程序如下:
/**
* 哈希表的开放地址法中的二次探测
*/
package com.eleven;
public class HashDoubleApp{
public static void main(String[] args) {
int size = 10;//哈希表长度
HashTable2 hashtable = new HashTable2(size);
/*int num = 8;//哈希表中数据项个数
int rate = 10;//比率为10,
for(int i =0;i<num;i++){
int value =(int)( Math.random()*rate*size);//表示关键字范围是120
//根据关键字创建数据项对象
Data2 data = new Data2(value);
//再根据数据项对象,新增哈希表
hashtable.insert(data);
}*/
int arr[] ={79,38,49,18,29};
for(int i =0;i<arr.length;i++){
Data2 data = new Data2(arr[i]);
hashtable.insert(data);
}
hashtable.display();
int findkey = 28;//设置要查找的关键值
Data2 finddata = hashtable.find(findkey);
if(finddata!=null)
System.out.println("找到"+findkey);
else
System.out.println("没找到"+findkey);
//删除操作
int deletekey = 18;
Data2 deletedata = hashtable.delete(deletekey);
if(deletedata!=null)
System.out.println("已经删除"+deletekey);
else
System.out.println("该哈希表中不含"+deletekey);
hashtable.display();
}
}
//数据类
class Data2{
private int data;
public Data2(int data){
this.data = data;
}
public int getData(){
return data;
}
}
//哈希表:增,删, 查,遍历
class HashTable2{
//定义一个数组,存放带关键值的数据项;定义数组的长度;定义被删除的数据项
private Data2 hashArr[] ;
private int arrlength;
private Data2 deleteData;
//构造函数,初始化三个变量
public HashTable2(int size){
arrlength = size;
hashArr = new Data2[arrlength];
deleteData = new Data2(-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(Data2 value){
if(!isFull()){
int key = value.getData();
int arrIndex = HashFunc(key);//得到哈希化的数组下标
//寻找哈希表中空的或者被删除的项
int i = 1;
while(hashArr[arrIndex]!=null && hashArr[arrIndex].getData()!=-1){
int step = i*i;
int index = arrIndex;
arrIndex += step;
arrIndex %= arrlength;
++i;
if(hashArr[arrIndex]!=null && hashArr[arrIndex].getData()!=-1){
arrIndex = index;
}
}
hashArr[arrIndex] = value;
}
}
//删:根据关键值删除对应的数据项
//先转化为数组下标,再得到数组此位置对应的数据项,然后查找,删除并返回
public Data2 delete(int key){
int arrIndex = HashFunc(key);
int temp = arrIndex;
int i =1;
while(hashArr[arrIndex]!= null){
if(hashArr[arrIndex].getData()== key){
Data2 data = hashArr[arrIndex];
hashArr[arrIndex] = null;
return data;
}
//如果当前为止没找到,继续找下一个
arrIndex +=(i*i);
++i;
arrIndex %= arrlength;
if(hashArr[arrIndex]!= null && hashArr[arrIndex].getData()!=-1 && hashArr[arrIndex].getData()!= key){
arrIndex = temp;
}
}
return null;//没有找到,
}
//查找
public Data2 find(int key){
int arrIndex = HashFunc(key);
int temp = arrIndex;
int i=1;
while(hashArr[arrIndex]!=null){
if(hashArr[arrIndex].getData()==key)
return hashArr[arrIndex];
//当前位置没有找到,继续往下一个位置找
arrIndex +=(i*i);
++i;
arrIndex %= arrlength;
if(hashArr[arrIndex]!=null && hashArr[arrIndex].getData()!=-1 && hashArr[arrIndex].getData()!= key){
arrIndex = temp;
continue;
}
}
return null;//没找到
}
//遍历
public void display(){
for(int i=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
没找到28
已经删除18
49 ** ** 29 ** ** ** ** 38 79