学习数据结构和算法的日常Demo
哈希表基本介绍
实际场景问题
思路分析
代码实现:
// 实体类
public class Employee {
public int id;
public String name;
public Employee next;
public Employee(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
// 类似哈希桶(HashMap中的内部类Node<K,V>)
// 包含对数据的操作
public class EmpLinkedList {
private Employee head; // 默认空
// 添加
// 尾插
public void add(Employee employee) {
// 头结点空,直接添加
if (head == null) {
head = employee;
return;
}
Employee curEmp = head;
while (curEmp.next != null) {
curEmp = curEmp.next;
}
// 尾插
curEmp.next = employee;
}
// 遍历
public void list(int tableId) {
if (head == null) {
System.out.println("链表编号(" + tableId + "):空!");
return;
}
Employee curEmp = head;
while (curEmp != null) {
System.out.print("链表编号(" + tableId + "):" + curEmp + "--->");
curEmp = curEmp.next; // 后移
}
System.out.println();
}
// 根据员工id获取实例
public Employee getEmpById(int id) {
if (head == null) {
System.out.println("链表空!");
return null;
}
Employee curEmp = head;
while (curEmp.id != id && curEmp != null) {
curEmp = curEmp.next;
if (curEmp.id == id) {
break;
}
}
return curEmp;
}
// 根据id删除员工
public void deleteEmpById(int id) {
if (head == null) {
System.out.println("链表空!");
return;
}
// 如果要删除的节点刚好为头结点
if (head.id == id) {
head = head.next;
System.out.println("删除成功");
} else {
Employee temp = head;
boolean flag = false; // 判断是否找到的标志
while (temp.next != null) {
if (temp.next.id == id) {
flag = true;
break;
}
temp = temp.next;
}
if (flag) {
temp.next = temp.next.next;
System.out.println("删除成功");
} else {
System.out.println("该节点不存在!");
}
}
}
}
// 具体的操作类
// 封装对哈希桶数组的具体操作
public class MyHashTable {
private EmpLinkedList[] table;
public MyHashTable(int size) {
this.table = new EmpLinkedList[size];
// 存储引用类型的数组,数组初始化后,也要为每个引用元素初始化
for (int i = 0; i < size; i++) {
table[i] = new EmpLinkedList();
}
}
// 添加
public void put(Employee employee) {
// 根据员工id得到员工该添加到哪条链表
// 散列,得到该去的table[i]
int tableId = hash(employee.id);
// 将员工添加到对应的链表中
table[tableId].add(employee);
}
// 遍历table
public void list() {
for (int i = 0; i < table.length; i++) {
table[i].list(i);
}
}
// 编写散列函数(简单取模)
public int hash(int id) {
return id % table.length;
}
// 根据员工id查找
public void get(int id) {
// 使用散列函数确定到哪条链表查找
int tableId = hash(id);
Employee emp = table[tableId].getEmpById(id);
if (emp != null) {
System.out.print("该员工所属链表(" + tableId + "):");
System.out.println(emp);
} else {
System.out.println("查不到该员工!");
}
}
// 根据员工id删除
public void remove(int id) {
// 使用散列函数确定到哪条链表查找
int tableId = hash(id);
table[tableId].deleteEmpById(id);
}
}
// 测试类
public class HashTableDemo {
public static void main(String args[]) {
MyHashTable myHashTable = new MyHashTable(7);
myHashTable.put(new Employee(11, "张三"));
myHashTable.put(new Employee(43, "李四"));
myHashTable.put(new Employee(28, "哈哈哈"));
myHashTable.put(new Employee(21, "王麻子"));
myHashTable.put(new Employee(42, "嘿嘿嘿"));
myHashTable.list();
System.out.println("---------------");
myHashTable.remove(42);
myHashTable.list();
}
}