哈希表
散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
1、关于哈希表的题
有一个公司,当有新的员工来报道时,要求将该员工信息加入(id,姓名,年龄),当输入该员工的id时,要求找到该员工的所有信息。
要求:不使用数据库,速度越快越好。
. 思路分析
有3个类:
EmpHashTable类:根据id散列每个存入的值;创建链表类型的数组
EmpLinkedList类:链表类,定义了头节点,对链表的增删改查的操作
Emp类:节点类,存入信息的类,以及next域
public class HashTable {
public static void main(String[] args) {
EmpHashTable empHashTable = new EmpHashTable(7);
System.out.println("添加数据中...");
empHashTable.add(new Emp(1,"lucy",20));
empHashTable.add(new Emp(1130,"heroc",21));
empHashTable.add(new Emp(134,"smith",20));
System.out.println("添加数据成功!");
empHashTable.show();
System.out.println("\n\n查找id为1130的员工信息:");
empHashTable.find(1130);
System.out.println("查找id为137的员工信息:");
empHashTable.find(137);
System.out.println("删除id为1的员工信息...");
empHashTable.del(1);
empHashTable.show();
}
}
// 链表的节点
class Emp{
public int id;
public String name;
public int age;
public Emp next; // 存储下一个实例
public Emp() {
}
public Emp(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Emp{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
// 创建一个链表,用链表把节点串起来
class EmpLinkedList{
private Emp head; // 头节点
private Emp curEmp; // 遍历用的辅助变量
public EmpLinkedList() {
}
public void add(Emp emp){
if (head == null){
head = emp;
return;
}
curEmp = head;
while (true){
if (curEmp.next == null){
curEmp.next = emp;
break;
}
curEmp = curEmp.next;
}
}
public Emp find(int id){
if (head == null){
return null;
}
curEmp = head;
while (true){
if (curEmp.id == id){
return curEmp;
}
if (curEmp.next == null){
return null;
}
curEmp = curEmp.next;
}
}
public void del(int id){
if (head == null){
return;
}
if (head.id == id){
head = head.next;
return;
}
curEmp = head;
while (true){
if (curEmp.next==null){
break;
}
if (curEmp.next.id == id){
curEmp.next = curEmp.next.next;
break;
}
curEmp = curEmp.next;
}
}
public void show(int id){
if (head == null){
return;
}
System.out.println("\n第"+(id+1)+"个数组链表,存入的数据:");
curEmp = head;
while (true){
System.out.print(curEmp.toString()+" => ");
curEmp = curEmp.next;
if (curEmp == null){
break;
}
}
}
}
// 创建一个哈希表,
class EmpHashTable{
private EmpLinkedList[] empLinkedLists; // 该数组存储每个链表
int size; // 用于初始化数组
public EmpHashTable(int size) {
this.size = size;
// 这里定义的创建了size大小的可以存入EmpLinkedList类型的数组空间
empLinkedLists = new EmpLinkedList[size];
// 这里是给每一个空间,存入一个实例化的空链表
for (int i = 0; i < empLinkedLists.length; i++) {
empLinkedLists[i] = new EmpLinkedList();
}
}
// 散列操作,散列操作有很多种,这里用了常见的取模方式
// 根据id把这个节点放入到对应的数组链表中
public int hashFun(int id){
return id % size;
}
public void add(Emp emp){
int index = hashFun(emp.id);
empLinkedLists[index].add(emp);
}
public void find(int id){
int index = hashFun(id);
Emp emp = empLinkedLists[index].find(id);
if (emp == null){
System.out.println("哈希表中没有id为"+id+"的数据!");
}else {
System.out.println(emp.toString());
}
}
public void del(int id){
int index = hashFun(id);
empLinkedLists[index].del(id);
}
public void show(){
for (int i = 0; i < empLinkedLists.length; i++) {
empLinkedLists[i].show(i);
}
}
}
结果:
添加数据中...
添加数据成功!
第2个数组链表,存入的数据:
Emp{id=1, name='lucy', age=20} => Emp{id=134, name='smith', age=20} =>
第4个数组链表,存入的数据:
Emp{id=1130, name='heroc', age=21} =>
查找id为1130的员工信息:
Emp{id=1130, name='heroc', age=21}
查找id为137的员工信息:
哈希表中没有id为137的数据!
删除id为1的员工信息...
第2个数组链表,存入的数据:
Emp{id=134, name='smith', age=20} =>
第4个数组链表,存入的数据:
Emp{id=1130, name='heroc', age=21} =>