import java.io.InputStreamReader;
import java.io.BufferedReader;/**
* @Class HashTableApp
* @Description 哈希表,开放地址法的线性探索算法
* @Company OpenData
* @author Chenlly
* @Date 2009-03-20
* @version 1.0 算法:关键字值的范围是从0到200,数组的初始化大小是20,一般为素数。哈希函数必须把关键字的范围压缩
* 到数组的范围,所以用到的哈希函数是求模函数 arrayIndex = key%arraySize
*/
class DataItem {
private int iData; public DataItem(int iData) {
this.iData = iData;
} public int getIData() {
return iData;
} public void setIData(int data) {
iData = data;
}}
public class HashTableApp {
private static final int MAX_SIZE = 20;
private DataItem[] intArray;
private DataItem nonItem;

//构造函数
public HashTableApp(int size){
intArray = new DataItem[size];
//填充数据项为-1对象
nonItem = new DataItem(-1);
}

// 哈希函数
public static int hashFunc(int key) {
return key % MAX_SIZE;
}

//显示哈希表中的数据,如果还没有数据项则以**填充,如果是被删除的数据项则以-1填充
public void display() {
System.out.println("The Table:");
for (int i = 0;i<MAX_SIZE;i++ ) {
if (intArray[i] != null){
System.out.print(intArray[i].getIData()+"");
} else {
System.out.print("**");
}
System.out.print(" ");
}
} // 插入数据项到哈希表中,经过哈希函数把关键字填充到数组,如果产出冲突,往后查找空白位,然后插入。
// 可能会出现分布不均匀,把一连串连续的填充单元叫做聚焦
public void insert(DataItem dataItem) {
int key = dataItem.getIData();
int hashValue = HashTableApp.hashFunc(key);
while (intArray[hashValue] != null && intArray[hashValue].getIData() != -1) {//为-1的数据项是删除了的数据项,可以再填充
hashValue++;
}
intArray[hashValue] = dataItem;
} // 如果对键入的关键字值经过哈希函数得到的数据下标就是要找的对象,则查找成功。否则冲突,产生冲突就的往后一个一个查找叫做探测
// 如果在探测过程中遇到空位说明查找失败,因为插入算法本应该把数据项插入这个位置的
public DataItem find(int key) {
int hashValue = HashTableApp.hashFunc(key);
while (intArray[hashValue] != null){
if (intArray[hashValue].getIData() == key){
return intArray[hashValue];
} else {
hashValue++;
hashValue %= MAX_SIZE;
}
}
return null;
} // 删除算法,是把要删除的关键字值对应的数组值置-1。
public DataItem delete(int key) {
int hashValue = HashTableApp.hashFunc(key);
while (intArray[hashValue] != null) {
if (intArray[hashValue].getIData() == key) {
DataItem temp = intArray[hashValue];
intArray[hashValue] = nonItem;
return temp;
} else {
hashValue++;
hashValue %= MAX_SIZE;
}
}
return null;
}

//从键盘上读取数据
public static String readStr() {
InputStreamReader ir = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(ir);
String str = "";
try {
str = br.readLine();
} catch (Exception ex) {
ex.printStackTrace();
}
return str;
}

//主调函数
public static void main(String []args){
System.out.println("请选择操作序列");
System.out.println("1 插入数据项");
System.out.println("2 通过key查找数据项");
System.out.println("3 删除一个数据项");
System.out.println("4 显示哈希表");
System.out.println("5 退出");
HashTableApp hashTableApp = new HashTableApp(MAX_SIZE);
while (true) {
System.out.println("");
System.out.println("请选择操作序列");
int op = Integer.parseInt(HashTableApp.readStr());
switch (op) {
case 1:
System.out.println("请输入数据项,范围0~200");
int nData = Integer.parseInt(HashTableApp.readStr());
DataItem dataItem = new DataItem(nData);
hashTableApp.insert(dataItem);
break;
case 2:
System.out.println("请输入需要查找的关键字");
int key = Integer.parseInt(HashTableApp.readStr());
DataItem findItem = hashTableApp.find(key);
if (findItem == null) {
System.out.println("查找失败");
} else {
System.out.println("the Data "+findItem.getIData());
}
break;
case 3:
System.out.println("请输入需要删除的关键字");
int delKey = Integer.parseInt(HashTableApp.readStr());
DataItem delItem = hashTableApp.delete(delKey);
if (delItem == null) {
System.out.println("删除失败");
} else {
System.out.println("the Data "+delItem.getIData()+"is deleted");
}
break;
case 4:
hashTableApp.display();
break;
case 5:
default:
System.exit(0);
}//end switch
}//end while
}//end main
}