/**
* Created by root on 16-3-11.
*/
import java.lang.Math;
public class QuadraticProbingHashTable<E> {
private static int DEFAULT_TABLE_SIZE = 11;
//fields
private int currentSize;
private HashEntry[] array;
// the HashTable's constructor :
public QuadraticProbingHashTable() {
this(DEFAULT_TABLE_SIZE);
}
public QuadraticProbingHashTable(int currentSize) {
allocateArray(currentSize);
makeEmpty();
}
//insert
public void insert(E x) {
int currentPos = findPos(x);
if (isActive(currentPos)) {
return;
}
array[currentPos] = new HashEntry(x);
if (++currentSize > array.length / 2) {
rehash();
}
}
//remove
public void remove(E x) {
int pos = findPos(x);
if (isActive(pos)) {
array[pos].isActive = false;
}
}
//rehash()
private void rehash() {
HashEntry[] oldArray = this.array;
allocateArray(nextPrime(oldArray.length * 2));
currentSize = 0;
for (int i = 0; i < oldArray.length; i++) {
if (oldArray[i] != null && oldArray[i].isActive) {
this.insert((E) oldArray[i].element);
}
}
}
//isActive:
public boolean isActive(int Pos) {
return array[Pos] != null &&
array[Pos].isActive
;
}
//int findPos(E x) recursive
private int findPos(E x){
int offset=1;
int currentPos=myHash(x);
while(array[currentPos]!=null && !array[currentPos].element.equals(x)){
currentPos+=offset;
offset+=2;
if(currentPos>=array.length){
currentPos-=array.length;
}
}
return currentPos;
}
//void makeEmpty()
public void makeEmpty() {
this.currentSize = 0;
for (int i = 0; i < array.length; i++) {
array[i] = null;
}
}
//myHash(E x)
private int myHash(E x) {
int hashVal = x.hashCode();
hashVal %= array.length;
if (hashVal < 0) {
return hashVal + array.length;
} else {
return hashVal;
}
}
//void allocate(int arraySize)
public void allocateArray(int arraySize) {
this.array = new HashEntry[nextPrime(arraySize)];
}
//int nextPrime(int n)
private int nextPrime(int n) {
int sqrt = (int) java.lang.Math.sqrt(n);
if (isPrime(n, sqrt)) {
return n;
} else {
return nextPrime(n + 1);
}
}
private boolean isPrime(int x, int y) {
if (y == 1) {
return true;
} else if (x % y == 0) {
return false;
} else {
return isPrime(x, y - 1);
}
}
//internal class constructor : HashEntry(E el,boolean i)
private static class HashEntry<E> { //internal class
public E element;
public boolean isActive;
public HashEntry(E element) {
this(element, true);
}
public HashEntry(E el, boolean i) {
this.element = el;
this.isActive = i;
}
}
}