散列函数,主要目的是需找一个好的散列方法把这个数组的每一个位置都能均匀的用到,下面先上一个比较好的散列函数实现
package com.bird.five;
/**
// *@castor.散列函数
* @author Bird
*
*/
public class Hash {
/**
* 一个较好的散列函数为String
* @param key任意一个String
* @param tableSize数组的长度
* @return
*/
public static int hash(String key, int tableSize){
int hashVal = 0;
for(int i = 0; i < key.length(); i++){
hashVal = 37 * hashVal + key.charAt(i);
}
hashVal %= tableSize;
if(hashVal < 0)
hashVal += tableSize;
return hashVal;
}
}
然后对于散列表的实现,主要又分离散列表和开放地址法,分离散列表就是在一个数组中,如果对于有地址冲突的数据,则放在一个横向的链表中进行保存,具体实现如下
package com.bird.five;
import java.util.LinkedList;
/**
* @category 分离散列表的实现
* @author Bird
*
*/
public class SeparateChainingHashTable {
private static final int DEAFAULT_TABLE_SIZE = 101;
//散列表的数组
private LinkedList<Object>[] theLists;
public SeparateChainingHashTable(){
this(DEAFAULT_TABLE_SIZE);
}
@SuppressWarnings("unchecked")
public SeparateChainingHashTable(int size){
theLists = new LinkedList[size];
for(int i = 0; i < theLists.length; i++)
theLists[i] = new LinkedList<Object>();
}
public void makeEmpty(){
for(int i = 0; i < theLists.length; i++)
theLists[i].clear();
}
public void remove(Hashable x){
theLists[x.hash(theLists.length)].remove(x);
}
public Hashable find(Hashable x){
return (Hashable)theLists[x.hash(theLists.length)].get(0);
}
}
interface Hashable{
int hash(int tableSize);
}
对于开散列法,如果又地址冲突的数据,则进行查找下一个地址是否没有使用,如果没有使用则插入,比较流行的是平方探测法比较好
package com.bird.five;
/**
* @category 开散列法的平方探测法的实现
* @author Bird
*
*/
class HashEntry{
Hashable element;//the element
boolean isActive;//懒惰删除的实现标记
public HashEntry(Hashable e){
this(e,true);
}
public HashEntry(Hashable e, boolean i){
element = e;
isActive = i;
}
}
public class QuadraticProbingHashTable {
private static final int DEAFAULT_TABLE_SIZE = 11;
private HashEntry[] array;
@SuppressWarnings("unused")
private int currentSize;
public QuadraticProbingHashTable(){
this(DEAFAULT_TABLE_SIZE);
}
public QuadraticProbingHashTable(int size){
allocateArray(size);
makeEmpty();
}
public void makeEmpty(){
currentSize = 0;
for(int i = 0; i < array.length; i++)
array[i] = null;
}
private void allocateArray(int arraySize) {
array = new HashEntry[arraySize];
}
/**
* 解决查找冲突问题
* @param x
* @return
*/
private int findPos(Hashable x){
int collisionNum = 0;
int currentPos = x.hash(array.length);
while(array[currentPos] != null && !array[currentPos].element.equals(x)){
currentPos += 2 * ++collisionNum - 1;
if(currentPos >= array.length)
currentPos -= array.length;
}
return currentPos;
}
public Hashable find(Hashable x){
int currentPos = findPos(x);
return isActive(currentPos)? array[currentPos].element : null;
}
private boolean isActive(int currentPos){
return array[currentPos] != null && array[currentPos].isActive;
}
}