哈希表(散列表)
增删改查
一、哈希表结构
二、源码
1.定义每个节点
代码如下(示例):
package Hashtable;
//先写出链表中每个节点表示的员工信息
public 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 "Emp{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
2.每个链表的定义
代码如下(示例):
package Hashtable;
//定义每个链表,其中按顺序加入每个节点,遍历链表
public class EmpLinkedlist {
//头结点就是一个员工节点
public Emp head;
//将Emp员工信息加入到链表中
public void add(Emp emp) {
//判断是不是空链表
if (head == null) {
head = emp;
return;
}
//定义一个临时指针,遍历到链表最后
Emp CurEmp = head;
while (true) {
if (CurEmp.next == null) {
break;
}
CurEmp = CurEmp.next;
}
CurEmp.next = emp;
}
//查找整个链表中的元素
public void list(int no) {
if (head == null) {
System.out.println("第"+no+"行链表为空");
return;
}
System.out.println("第"+no+"行链表信息为:");
Emp CurEmp = head;
while (true) {
if (CurEmp== null) {
break;
}
System.out.println(CurEmp);
CurEmp = CurEmp.next;
}
}
//查找指定员工在不在链表中 如果找到就返回id和姓名 找不到就返回null
public Emp findEmp(int id) {
if (head == null) {
System.out.println("链表为空");
return null;
}
Emp CurEmp = head;
while (true) {
if (CurEmp == null) {
break;
}
if (CurEmp.id == id) {
break;
}
CurEmp = CurEmp.next;
}
return CurEmp;
}
//删除链表中的指定节点 找到就删除
public void deleteEmp(int id) {
if (head == null) {
System.out.println("第"+id+"链表为空");
return;
}
Emp CurEmp = head;
boolean flag = false;
if (CurEmp.id == id) {
head = CurEmp.next;
return;
}
while (true) {
if (CurEmp.next.id == id) {
break;
}
if (CurEmp == null) {
flag = true;
break;
}
CurEmp = CurEmp.next;
}
if (flag == false) {
CurEmp.next = CurEmp.next.next;
} else {
System.out.println("没有找到标号为" + id + "的员工");
}
}
}
3.数组的定义
代码如下(示例):
package Hashtable;
public class HashTab {
public EmpLinkedlist[] empLinkedlistArray;
//添加构造方法
public HashTab(int size) {
empLinkedlistArray = new EmpLinkedlist[size];
//初始化各行链表
for (int i = 0; i < size; i++) {
empLinkedlistArray[i] = new EmpLinkedlist();
}
}
//编写一个散列函数
public int hashFun(int id) {
return id % empLinkedlistArray.length;
}
//将一个节点添加到hashtable中
public void addEmp(Emp emp) {
int emplinkedlistno = hashFun(emp.id);
empLinkedlistArray[emplinkedlistno].add(emp);
}
//遍历所有链表
public void list() {
for (int i = 0; i < empLinkedlistArray.length; i++) {
empLinkedlistArray[i].list(i);
}
}
//查找员工编号为no的员工信息
public void FindEmp(int no) {
int emplinkedlistno = hashFun(no);
Emp emp = empLinkedlistArray[emplinkedlistno].findEmp(no);
if (emp == null){
System.out.printf("没有找到标号为%d\n",no);
}else {
System.out.printf("员工标号为%d,姓名为%s\n",emp.id,emp.name);
}
}
//删除员工编号为no的员工信息
public void deleteemp(int no){
int emplinkedlistno = hashFun(no);
empLinkedlistArray[emplinkedlistno].deleteEmp(no);
}
}
4.Demo
代码如下(示例):
package Hashtable;
import java.util.Scanner;
public class HashTabDemo {
public static void main(String[] args) {
HashTab hashTab = new HashTab(7);
String key = "";
Scanner scanner = new Scanner(System.in);
while(true){
System.out.println("search:查找编号为no的员工");
System.out.println("delete:删除编号为no的员工");
System.out.println("list:遍历全部hashtable");
System.out.println("add:添加一个节点");
System.out.println("exit:退出程序");
key = scanner.next();
switch (key){
case "search":
System.out.println("输入一个编号");
int no = scanner.nextInt();
hashTab.FindEmp(no);
break;
case "delete":
System.out.println("输入一个编号");
no = scanner.nextInt();
hashTab.deleteemp(no);
break;
case "list":
hashTab.list();
break;
case "add":
System.out.println("请输入编号");
no = scanner.nextInt();
System.out.println("请输入姓名");
String name = scanner.next();
Emp emp = new Emp(no,name);
hashTab.addEmp(emp);
break;
case "exit":
scanner.close();
System.exit(0);
break;
default:
break;
}
}
}
}
总结
实质为:数组+链表
关键为单向链表的编写,然后利用散列函数套入数组。
散列函数这里很简单,可以自己设置复杂。