哈希表的开放地址发中的二次探测虽然消除了线性探测的首次聚集问题,但是又产生了新的问题:二次聚集。
二次聚集产生的原因是:所有映射到同一个单元的关键字,在探测过程中执行了相同的序列。即二次聚集会发生是因为探测序列总是相同的。即步长只依赖于哈希函数,与关键字无关。
在再哈希法中,步长依赖于关键字,且从第二个哈希函数中得到。如果第二个哈希函数返回一个值s,则探测序列是:
x, x+s, x+2s, x+3s, x+4s, ...
/**
* 哈希表,再哈希法(两个哈希函数,一个确定原始位置,一个确定步长)*/
package com.eleven;
public class HashAgainApp {
public static void main(String[] args) {
int size = 23;
HashAgain hashtable = new HashAgain(size);
int[] arr = {1,38,37,16,20,3,11,24,5,16,10,31,18,12,30,1,19,36,41,15,25};
for(int i = 0;i<arr.length;i++){
Data3 data = new Data3(arr[i]);
hashtable.insert(data);
}
hashtable.display();
int findkey = 20;//设置要查找的关键值
Data3 finddata = hashtable.find(findkey);
if(finddata!=null)
System.out.println("找到"+findkey);
else
System.out.println("没找到"+findkey);
//删除操作
int deletekey = 18;
Data3 deletedata = hashtable.delete(deletekey);
if(deletedata!=null)
System.out.println("已经删除"+deletekey);
else
System.out.println("该哈希表中不含"+deletekey);
hashtable.display();
}
}
//数据类
class Data3{
private int data;
public int getData(){
return data;
}
public Data3(int data){
this.data = data;
}
}
//哈希表类
class HashAgain{
private Data3[] hashArr ;
private int arrlen;
private Data3 deletedata;
public HashAgain(int size){
arrlen = size;
hashArr = new Data3[arrlen];
deletedata = new Data3(-1);
}
//哈希函数1
public int HashFunc1(int key){
return key % arrlen;
}
//哈希函数2
public int HashFunc2(int key){
//不能是0,不能和哈希函数1一样
return 5-key % 5;
}
//增
public void insert(Data3 data){
if(!isFull())
{
int key = data.getData();
int index = HashFunc1(key);
int step = HashFunc2(key);
while(hashArr[index]!=null && hashArr[index].getData()!=-1){
index += step;
index %= arrlen;
}
hashArr[index] = data;
}
}
//删
public Data3 delete(int key){
int index = HashFunc1(key);
int step = HashFunc2(key);
while(hashArr[index]!=null && hashArr[index].getData()!=-1){
if(hashArr[index].getData()==key){
Data3 temp = hashArr[index];
hashArr[index] = deletedata;
return temp;
}
index += step;
index %= arrlen;
}
return null;
}
//查找
public Data3 find(int key){
int index = HashFunc1(key);
int step = HashFunc2(key);
while(hashArr[index]!=null && hashArr[index].getData()!=-1){
if(hashArr[index].getData()==key){
return hashArr[index];
}
index += step;
index %= arrlen;
}
return null;
}
//判断是否满
public boolean isFull()
{
int len = 0;
while(hashArr[len]!= null && len<arrlen){
++len;
}
if(len==arrlen)
return true;
else
return false;
}
//遍历
public void display(){
int len=0;
while(len<arrlen){
if(hashArr[len]!=null)
System.out.print(hashArr[len].getData()+" ");
else
System.out.print("** ");
len += 1;
}
System.out.println();
}
}
结果是:
** 1 24 3 15 5 25 30 31 16 10 11 12 1 37 38 16 36 18 19 20 ** 41
找到20
已经删除18
** 1 24 3 15 5 25 30 31 16 10 11 12 1 37 38 16 36 -1 19 20 ** 41