哈希表:哈希表是一种数据结构,它提供了快速的插入操作和查找操作,其基于数组来实现。
哈希化方式
1)直接将关键字作为索引。
弊端:关键字数据类型只能是整形。
2)将单词转换成索引。
①将字母转换成ASCII码,然后进行相加。
弊端:会出现不同的字符串转换ASCII码的值和相同。
②幂的连乘。
弊端:通过幂的连乘得到的key一般非常大。
③压缩可选值。
弊端:不能保证每个单词都映射到数组的空白单元。
解决方式:
- 开放地址法
- 链地址法
直接将关键字作为索引:
创建一个对象:
public class Info {
private int key;
private String name;
public Info(int key, String name) {
this.key = key;
this.name = name;
}
public int getKey() {
return key;
}
public void setKey(int key) {
this.key = key;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
创建一个哈希表,使用存储对象中的关键字作为数组的索引
public class HashTable {
private Info[] arr;
/**
* 默认构造方法
*/
public HashTable() {
arr = new Info[100];
}
public HashTable(int maxSize) {
arr = new Info[maxSize];
}
/**
* 插入数据
*
* @param info
*/
public void insert(Info info) {
// 将info中的key作为数组的索引
arr[info.getKey()] = info;
}
/**
* 查找操作
*
* @param key
* @return
*/
public Info find(int key) {
return arr[key];
}
}
将单词转换成索引
①将字母转换成ASCII码,然后进行相加。
创建存储对象类
public class Info {
private String key;
private String name;
public Info(String key, String name) {
this.key = key;
this.name = name;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
创建哈希类
public class HashTable {
private Info[] arr;
/**
* 默认构造方法
*/
public HashTable() {
arr = new Info[100];
}
public HashTable(int maxSize) {
arr = new Info[maxSize];
}
/**
* 插入数据
*
* @param info
*/
public void insert(Info info) {
// 将info中的key作为数组的索引
arr[hashCode(info.getKey())] = info;
}
/**
* 查找操作
*
* @param key
* @return
*/
public Info find(String key) {
return arr[hashCode(key)];
}
/**
* 将字符串字母转换为ASCII码,然后相加
*
* @param key
* @return
*/
public int hashCode(String key) {
int hashValue = 0;
for (int i = key.length() - 1; i >= 0; i--) {
int letter = key.charAt(i) - 96;
hashValue += letter;
}
return hashValue;
}
}
②幂的连乘。
存储对象类同上。
创建哈希表类。
public class HashTable {
private Info[] arr;
/**
* 默认构造方法
*/
public HashTable() {
arr = new Info[100000];
}
public HashTable(int maxSize) {
arr = new Info[maxSize];
}
/**
* 插入数据
*
* @param info
*/
public void insert(Info info) {
// 将info中的key作为数组的索引
arr[hashCode(info.getKey())] = info;
}
/**
* 查找操作
*
* @param key
* @return
*/
public Info find(String key) {
return arr[hashCode(key)];
}
/**
* 将字符串字母转换为ASCII码,然后跟一个指定的数字的幂相乘
*
* @param key
* @return
*/
public int hashCode(String key) {
int hashValue = 0;
// 指定一个数字
int pow27 = 1;
for (int i = key.length() - 1; i >= 0; i--) {
int letter = key.charAt(i) - 96;
hashValue += letter * pow27;
pow27 *= 27;// pow27的幂每次加1,该数字的底数为27
}
return hashValue;
}
}
③压缩可选值。
存储对象类同上。
创建哈希表类。
public class HashTable {
private Info[] arr;
/**
* 默认构造方法
*/
public HashTable() {
arr = new Info[100];
}
public HashTable(int maxSize) {
arr = new Info[maxSize];
}
/**
* 插入数据
*
* @param info
*/
public void insert(Info info) {
// 将info中的key作为数组的索引
arr[hashCode(info.getKey())] = info;
}
/**
* 查找操作
*
* @param key
* @return
*/
public Info find(String key) {
return arr[hashCode(key)];
}
/**
* 将字符串字母转换为ASCII码,然后跟一个指定的数字的幂相乘,得到的结果进行取模
*
* @param key
* @return
*/
public int hashCode(String key) {
// 使用BigInteger而不用int,避免数组越界问题
BigInteger hashValue = new BigInteger("0");
// 指定一个数字
BigInteger pow27 = new BigInteger("1");
for (int i = key.length() - 1; i >= 0; i--) {
int letter = key.charAt(i) - 96;
BigInteger letterB = new BigInteger(String.valueOf(letter));
hashValue = hashValue.add(letterB.multiply(pow27));
pow27.multiply(new BigInteger("27"));// pow27的幂每次加1,该数字的底数为27
}
return hashValue.mod(new BigInteger(String.valueOf(arr.length)))
.intValue();
}
}