/*
* 平方探测采用原哈希值加整数平方作为备选位置避免了一次聚集
* 会产生二次聚集,在备选位置上聚集
* 装填因子不能大于0.5,即至少有一半为空且表大小为素数才能保证插入元素总能成功
*/
public class QuadraticProbingHashTable(){
public QuadraticProbingHashTable(){
this(DEFAULT_TABLE_SIZE);
}
public QuadraticProbingHashTable(int size){
allocateArray(size);
}
private static class HashEntry<AnyType>{
public AnyType element;
public booblean isActive;
public HahEntry(AnyType x){
this(e,true);
}
public HashEntry(AnyType x,boolean i){
element=e;
isActive=i;
}
}
private static final int DEFAULT_TABLE_SIZE=11;
private HashEntry<AnyType>[] array;
public void makeEmpty(){
for(int j=0;j<array.length;j++){
array[i].element=null;
array[i].isActive=false;
}
}
public booblean contains(AnyType x){
int CurrentPos=findPos(AnyType);
return isActive(currentPos);
}
public void insert(AnyType){
int pos=findPos(x);
if(isActive(pos))
return;
array[pos]=new HashEntry<AnyType>(x,ture);
if(++currentPos>array.length/2)
rehash();
}
/*
*删除只是将元素标记为删除
*/
public void remove(AnyType x){
int currentPos=findPos(x);
if(isActive(currentPos));
array[currentPos].isActive=false;
}
private allocateArray(int arraySize){
array=new HashEntry[arraySizee];
}
/*
* HashEntry引用数组有三种情况
* 1null
* 2非null,该项是活动的(isActive=true)
* 3非null,该项标记W为删除(isActive=false)
*/
private boolean isActive(int currentSize){
return array[currentPos]!=null&array[currentPos].isActive;
}
private int findPos(AnyType x){
int offset=1;
int currentPos=myhash(x);
while(array[currentPos]!=null&&!array[currentPos].element.equals(x)){
currentPos+=offset;
offset+=2;//下一个备选位置和上一个备选位置差2i+1,避免了乘除
if(currentPos>=arraySize)
currentPos-=arraySize;
}
return currentPos;
}
private int myhash(AnyType x){
int hashVal=x.hashCode();//应当是关键字求值
hashVal%=theLists.length;
if(hashVal<0){
hashVal+=theLists.length;
}
return hashVal;
}
/*
*平方探测再散列
*/
private void rehash(){
HashEntry<AnyType>[] oldArray=array;
allocateArray(nextPrime(2*oldArray.length));
currentSize=0;
//copy
for(int i=0;i<oldArray.length;i++){
if(oldArray[i]!=null&&oldArray[i].isActive){
insert(oldArray[i].element);
}
}
}
/*
*@return 包括n在内的之后的第一个素数
*/
private static int nextPrime(int n){
while(!isPrime(n)){
++n;
}
return n;
}
/*
*素数判断
*/
private static boolean isPrime(int n){
for(int i=2;i<sqrt(n);i++){
int k=n%i;
if(k==0){
return false;
}
}
return true;
}
}
散列表平方探测法
最新推荐文章于 2024-10-03 22:26:28 发布