HashTable的注意事项:
1.根据解决冲突的方案,分为CloseHash和OpenHash
CloseHash:用内部的HashArray的emptyCell存储冲突数据,由此得名。
计算冲突数据位置方法有三种:线性探索,二次探索,再哈希化。(超出面试范畴)
OpenHash:用链表Chaining存储冲突数据,由此得名。
2.常用的哈希函数为 hashVal = key%arraySize;
e.g. 143%60=143-60-60=23;
143%10=143-10-10-......-10=3 (对十取余就是取尾数)
3.hashArray的大小最好是素数(e.g. 59)
4.wrap around的实现为 hashVal%=arraySize
---------------------------------------------------------------
以下为CloseHash的线性探索代码
1.HashTable的构造函数:构造了两个Object(hashArray和nonItem)
2.insert:while循环条件【hashArrayCell非空&&非-1】hashVal increment
0- ..... 21 33 Bingo(here null or -1) .... 58-
3.delete&find:while循环条件【hashArrayCell非空】(如果是空,说明没有此元素),查找或删除。
来源于《Lafore》,hashTable单纯存取int,所以是HashSet,不是HashMap。
import java.io.*;
//
class DataItem{
private int data;
public DataItem(int data){
this.data=data;
}
public int getKey(){
return data;
}
}
class HashTable{
private DataItem[] hashArray;
private int arraySize;
private DataItem nonItem;
public HashTable(int arraySize){
this.arraySize=arraySize;
hashArray=new DataItem[arraySize];
nonItem=new DataItem(-1);
}
public int hashFunc(int key){
return key%arraySize;
}
/
public void insert(DataItem item){
int key=item.getKey();
int hashVal=hashFunc(key);
while(hashArray[hashVal]!=null && hashArray[hashVal].getKey()!=-1){
hashVal++;
hashVal%=arraySize;
}
hashArray[hashVal]=item;
}
/
public DataItem delete(int key){
int hashVal=hashFunc(key);
while(hashArray[hashVal]!=null){
if(hashArray[hashVal].getKey()==key){
DataItem temp=hashArray[hashVal];
hashArray[hashVal]=nonItem;
return temp;
}
hashVal++;
hashVal%=arraySize;
}//end while
return null;
}
//
public DataItem find(int key){
int hashVal=hashFunc(key);
while(hashArray[hashVal]!=null){
if(hashArray[hashVal].getKey()==key){
return hashArray[hashVal];
}
hashVal++;
hashVal%=arraySize;
}
return null;
}
public void display(){
System.out.println("HashTable:");
for(int i=0;i<arraySize;i++){
if (hashArray[i]!=null)
System.out.print(hashArray[i].getKey()+" ");
else
System.out.print("null ");
}
System.out.println();
}
}
//
class HashTableDemo{
public static void main(String[] args) throws IOException{
DataItem aDataItem;
int aKey,size,n,keysPerCell;
System.out.print("Enter size of hash table: ");
size=getInt();
System.out.print("Enter init number of items: ");
n=getInt();
keysPerCell=10;
HashTable demoHashTable = new HashTable(size);
for(int i=0;i<n;i++){
aKey=(int)(java.lang.Math.random()*keysPerCell*size);
aDataItem=new DataItem(aKey);
demoHashTable.insert(aDataItem);
}//end for
while(true){
System.out.print("Enter first letter of these: ");
System.out.print("insert,delete,find,showTable: ");
char choice=getChar();
switch(choice){
case 's':
demoHashTable.display();
break;
case 'i':
System.out.print("Enter key of item to insert: ");
aKey=getInt();
aDataItem=new DataItem(aKey);
demoHashTable.insert(aDataItem);
break;
case 'd':
System.out.print("Enter key of item to delete: ");
aKey=getInt();
demoHashTable.delete(aKey);
break;
case 'f':
System.out.print("Enter key of item to find: ");
aKey=getInt();
aDataItem=demoHashTable.find(aKey);
if (aDataItem!=null)
System.out.println("Find "+aKey);
else
System.out.println("Cannot find "+aKey);
break;
default:
System.out.println("Invalid entry!");
}//end switch
}//end while
}//end main()
public static String getString() throws IOException{
InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader br=new BufferedReader(isr);
String s=br.readLine();
return s;
}//end getString()
public static char getChar() throws IOException{
String s=getString();
return s.charAt(0);
}//end getChar()
public static int getInt() throws IOException{
String s=getString();
return Integer.parseInt(s);
}//end getInt()
}//end class