目录
一:哈希表的思想
哈希碰撞:数据丢失
避免哈希碰撞
散列函数选好,混匀分配
key极小的变化引起哈希值较大的变化
二:开发地址法
当值传进来的时候,通过散列函数得到哈希值(数组下标),当改下标存在数值的时候就需要哈希值+1,如下图(5 -> 6 -> 7 -> 8);
当内存不够了,可设计为循环数组(可参考我前面的循环链表),当没有空间的时候没办法插入值,此时需要扩充内存,势必浪费空间
三:链地址法(HashMap)
数组+链表
如果出现哈希冲突,就地生成一个链表
四:链地址法哈希表代码
4.1 汽车结点的定义
package hashmap;
public class Car {
private int id;
private String name;
private Car next;
public Car(int id, String name) {
this.id = id;
this.name = name;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return this.id;
}
public String getName() {
return this.name;
}
public void setNext(Car next) {
this.next = next;
}
public Car getNext() {
return this.next;
}
}
4.2 汽车链表的定义
package hashmap;
public class CarList {
private Car head;
//添加汽车
public void add(Car car) {
if(head == null) {
head = car;
return;
}
Car temp = head;
while(true) {
if(temp.getNext() == null) {
break;
}
temp = temp.getNext();
}
temp.setNext(car);
}
//查找汽车链表
public void search(int no) {
if(head == null) {
System.out.printf("第%d个链表为空...\n", no);
return;
}
Car temp = head;
while(true) {
System.out.printf("第%d个链表:汽车编号 = %d, 汽车名字 = %s\n",no, temp.getId(), temp.getName());
if(temp.getNext() == null) {
break;
}
temp = temp.getNext();
}
}
//查找汽车编号
public Car searchId(int id) {
if(head == null) {
System.out.println("汽车链表为空...");
return null;
}
Car temp = head;
while(true) {
if(temp.getId() == id) {
break;
}
if(temp.getNext() == null) {
temp = null;
break;
}
temp = temp.getNext();
}
return temp;
}
}
4.3 哈希表的设计
package hashmap;
public class HashArr {
private int max;
private CarList[] cl;
public HashArr(int max) {
this.max = max;
cl = new CarList[max];
for(int i = 0; i < max; i++) {
cl[i] = new CarList();
}
}
//散列函数
private int HashCodes(int id) {
return id%max;
}
//添加
public void add(Car car) {
int val = HashCodes(car.getId());
cl[val].add(car);
}
//查看链表
public void list() {
for(int i = 0; i < cl.length; i++) {
cl[i].search(i);
}
}
//按编号查看
public void listId(int id) {
int val = HashCodes(id);
Car c = cl[val].searchId(id);
if(c == null) {
System.out.println("该汽车不存在...");
}
if(c != null) {
System.out.printf("在第%d条链表中找到了该车:编号 = %d,姓名=%s\n", val, c.getId(), c.getName());
}
}
}
4.4 测试
package hashmap;
public class Test {
public static void main(String[] args) {
//添加
Car car1 = new Car(1,"大众");
Car car2 = new Car(2,"宝马");
Car car3 = new Car(3,"奥迪");
Car car4 = new Car(4,"帕萨特");
Car car5 = new Car(10,"凯迪拉克");
HashArr arr = new HashArr(6);
arr.add(car1);
arr.add(car2);
arr.add(car3);
arr.add(car4);
arr.add(car5);
arr.list();
arr.listId(10);
}
}