散列表(Hash table),也叫哈希表,是根据关键码值(Key value)而直接进行访问的数据结构。它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,名字,住址等),当输入该员工的 id 时,要求查找到该员工的所有信息。
public class HashTabDemo { public static void main(String[] args) { //创建哈希表 HashTab hashTab = new HashTab(7); hashTab.add(new Emp(1, "Tom")); hashTab.add(new Emp(2, "Jerry1")); hashTab.add(new Emp(9, "Jerry2")); hashTab.add(new Emp(16, "Jerry3")); hashTab.add(new Emp(23, "Jerry4")); hashTab.add(new Emp(8, "Dog")); hashTab.list(); hashTab.del(99); hashTab.list(); // hashTab.findEmpById(88); } } //创建HashTab,管理多个链表 class HashTab { private EmpLinkedList[] empLinkedListArray; private int size; //表示有多少个链表 //构造器 public HashTab(int size) { this.size = size; //初始化empLinkedListArray数组 empLinkedListArray = new EmpLinkedList[size]; //初始化每个链表 for (int i = 0; i < size; i++) { empLinkedListArray[i] = new EmpLinkedList(); } } //添加雇员 public void add(Emp emp) { //根据员工id得到员工应添加到哪个链表 int empLinkedListNO = hashFun(emp.id); //添加到链表中 empLinkedListArray[empLinkedListNO].add(emp); } //遍历hashtab,即所有链表 public void list() { for (int i = 0; i < size; i++) { empLinkedListArray[i].list(i); } } //根据id查找雇员 public void findEmpById(int id) { //确定到哪个链表找 int empLinkedListNO = hashFun(id); Emp emp = empLinkedListArray[empLinkedListNO].findEmpById(id); if (emp != null) { //找到 System.out.println("链表" + (empLinkedListNO + 1) + "中找到雇员" + emp.name); } else { //没找到 System.out.println("未找到此雇员"); } } //删除雇员 public void del(int id) { //确定到哪个链表删除 int empLinkedListNO = hashFun(id); empLinkedListArray[empLinkedListNO].del(id); } //散列函数,取模法 public int hashFun(int id) { return id % size; } } //雇员类 class Emp { public int id; public String name; public Emp next; public Emp(int id, String name) { this.id = id; this.name = name; } @Override public String toString() { return "id=" + id + ", name='" + name + '\''; } } //链表 class EmpLinkedList { //头指针,指向第一个Emp private Emp head; //添加雇员 //假定id自增长,将雇员加到链表最后即可 public void add(Emp emp) { //如果是第一个雇员 if (head == null) { head = emp; return; } //不是第一个雇员 Emp curEmp = head; while (curEmp.next != null) { curEmp = curEmp.next; } curEmp.next = emp; } //遍历雇员 public void list(int no) { if (head == null) { System.out.println("链表" + (no + 1) + "为空"); return; } Emp curEmp = head; System.out.println("链表" + (no + 1) + ": "); while (curEmp != null) { System.out.println(curEmp); curEmp = curEmp.next; } } //根据id查找雇员 public Emp findEmpById(int id) { //判断链表为空 if (head == null) { System.out.println("链表为空"); return null; } Emp curEmp = head; while (curEmp.id != id) { curEmp = curEmp.next; if (curEmp == null) { break; } } return curEmp; } //删除雇员 public void del(int id) { //判断链表为空 if (head == null) { System.out.println("链表为空"); return; } Emp curEmp = head; boolean flag = false; //如果找的是第一个节点 if (curEmp.id == id) { head = curEmp.next; return; } while (curEmp.next != null) { if (curEmp.next.id == id) { flag = true; //标识已找到 break; } curEmp = curEmp.next; } if (flag) { curEmp.next = curEmp.next.next; } else { System.out.println("未找到要删除的节点"); } } }