package com.algorithm.charactor1;
/**
* 和线性探测法差不多 ,寻找的下标不一样而已。
* 就是,中文版的类名,get到没
*/
public class 平方探测法 {
private HashEntry[] array ;//可以是任意泛型
private int currentSize;
private static int DEFAULTSIZE = 5;//随便写的数字
public int myHash(HashEntry entry){
int hashCode = entry.hashCode();
int index = hashCode % array.length;
index = index < 0 ? index + array.length : index;
return index;
}
public 平方探测法() {
this(DEFAULTSIZE);
}
public void insert(HashEntry entry) {
rehash();//扩容操作
int myHash = myHash(entry);//通过key计算到hash值即是对应的数组下表
int i = 0;
if (array[myHash] == null) {//没值就赋值
array[myHash] = entry;
}else {//当前位置被占用,同时需要进行扩容操作,需保证可以存放的元素大于数组的一半,不然会有插入失败可能
while(array[myHash]!=null){
i++;
myHash = myHash+ i*i;
myHash = myHash > array.length ? myHash -array.length:myHash;
if (array[myHash] == null) {
array[myHash] = entry;
break;
}
}
}
currentSize++;
}
private void rehash() {
if (currentSize > array.length /2) {
HashEntry [] oldArray =array;
HashEntry [] newArray = new HashEntry[nextPrime(array.length*2)];
System.out.println("扩容后"+nextPrime(array.length*2));
array = newArray;
currentSize =0;
for (HashEntry hashEntry : oldArray) {
if (hashEntry!=null) {
insert(hashEntry);
}
}
}
}
public 平方探测法(int size) {
array = new HashEntry[nextPrime(size)];//初始化数组的容量
}
class HashEntry{
private boolean isDelete;//如果被删除 标记为true
private String key;
public HashEntry(boolean isDelete, String key) {
super();
this.isDelete = isDelete;
this.key = key;
}
public HashEntry() {
super();
}
@Override
public int hashCode() {
return key.hashCode();
}
}
//素数计算,网上抄的
public static Integer nextPrime(Integer begin) {
int i;
int j;
for (i = begin;; i++) {
boolean flag = true;
for (j = 2; j <= i / 2; j++) {
if (i % j == 0) {
flag = false;
break;
} else if (i % j != 0) {
continue;
} else {
break;
}
}
if (flag) {
return i;
}
}
}
public static void main(String[] args) {
平方探测法 平方探测法 = new 平方探测法();
for (int i = 0; i < 100; i++) {
平方探测法.insert(平方探测法.new HashEntry(false, String.valueOf(i)));
System.err.println(i);
}
}
}