哈希函数: 使用特定的哈希算法,将关键字哈希化,压缩到一个较小的范围
哈希表: 使用哈希算法, 把一个大范围的数字哈希化成一个小范围的数字。 这个小范围对应着数组的下标。 使用哈希函数向数组插入数据后, 这个数组称为哈希表
链地址法: 开放地址法中,通过在哈希表中寻找一个空位解决哈希冲突问题。另一个方法是在哈希表每个单元中设置链表。某个数据项的关键字还是像通常一样映射到哈希表的单元,而数据项本身插入到这个单元的链表中。
装填因子: 链地址法中的装填因子(数据项数和哈希表容量的比值)与开发地址法的不同。 在链地址法中,需要在有N个单元的数组中装入N个或更多的数据项;因此装填因子一般为1,或比一大。 这没问题;因为,某些位置包含的链表中包含两个或两个以上的数据项。
下面将使用链地址法 实现哈希表并解决哈希冲突问题
1. 创建一个link类
public class Link {
private int iData;
public Link next;
public Link(int it){
this.iData = it;
}
public int getKey(){
return iData;
}
public void displayLink(){
System.err.print(iData+" ");
}
}
2. 创建一个SortedList类
public class SortedList {
private Link first;
public void SortedList(){
first = null;
}
public void insert(Link theLink){
int key = theLink.getKey();
Link previous =null;
Link current = first;
while(current !=null && key> current.getKey()){
previous = current;
current = current.next;
}
if (previous ==null){
first = theLink;
}else{
previous.next = theLink;
theLink.next = current;
}
}
public void delete(int key){
Link previous = null;
Link current = first;
while(current !=null && key != current.getKey()){
previous = current;
current = current.next;
}
if (previous == null){
first = first.next;
}else{
previous.next = current.next;
}
}
public Link find(int key){
Link current = first;
while(current!=null && current.getKey()<= key){
if (current.getKey() == key){
return current;
}
current = current.next;
}
return null;
}
public void displayList(){
System.out.print("List (first --> last):");
Link current = first;
while(current!=null ){
current.displayLink();
current = current.next;
}
System.out.print("");
}
}
3. 使用链地址法实现哈希表
public class LinkHashTable {
private SortedList[] hashArray;
private int arraySize;
public LinkHashTable(int size){
arraySize = size;
hashArray = new SortedList[arraySize];
for (int j=0; j<arraySize; j++){
hashArray[j] = new SortedList();
}
}
public void displayTable(){
for (int j = 0; j<arraySize;j++){
System.out.print(j+ ". ");
hashArray[j].displayList();
}
}
public int hashFunc(int key){
return key % arraySize;
}
public void insert (Link theLink){
int key = theLink.getKey();
int hashVal = hashFunc(key);
hashArray[hashVal].insert(theLink);
}
public void delete(int key){
int hashVal = hashFunc(key);
hashArray[hashVal].delete(key);
}
public Link find(int key){
int hashVal = hashFunc(key);
Link theLink = hashArray[hashVal].find(key);
return theLink;
}
}
4. 编辑测试类
public class HashChainApp {
public static void main(String[] args) throws IOException{
int aKey;
Link aDataItem;
int size, n, keysPerCell = 100;
System.out.print("Enter size of hash table: ");
size = getInt();
System.out.print("Enter initial number of items: ");
n =getInt();
LinkHashTable theHashTable = new LinkHashTable(size);
for (int j=0; j<n; j++){
aKey = (int) (Math.random() * keysPerCell * size);
aDataItem = new Link(aKey);
theHashTable.insert(aDataItem);
}
while(true){
System.out.print("Enter first letter of");
System.out.print(" show, insert, delete, or find: ");
char choice = getChar();
switch(choice){
case 's':
theHashTable.displayTable();
break;
case 'i':
System.out.print("Entry key value to insert: ");
aKey = getInt();
aDataItem = new Link(aKey);
theHashTable.insert(aDataItem);
break;
case 'd':
System.out.print("Enter key value to delete: ");
aKey = getInt();
theHashTable.delete(aKey);
break;
case 'f':
System.out.print("Enter key value to find: ");
aKey = getInt();
aDataItem = theHashTable.find(aKey);
if (aDataItem !=null){
System.out.print("Found " + aKey);
}else{
System.out.println("could not find " +aKey);
}
break;
default:
System.out.print("Invalid entry\n");
}
}
}
public static String getString() throws IOException{
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String s = br.readLine();
return s;
}
public static char getChar() throws IOException{
String s = getString();
return s.charAt(0);
}
public static int getInt() throws IOException{
String s = getString();
return Integer.parseInt(s);
}
}

本文介绍了哈希表的概念,利用哈希函数将关键字压缩到数组下标,通过链地址法处理哈希冲突。在链地址法中,每个哈希表单元包含一个链表,数据项根据关键字映射到相应单元并插入链表。同时讨论了装填因子在链地址法中的特点,并提供了使用链地址法实现哈希表的步骤:创建link类、SortedList类,以及测试类。
9080

被折叠的 条评论
为什么被折叠?



