哈希表
哈希表也叫散列表,是根據關鍵碼值而直接進行訪問的數據結構,通過把關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度。這個映射函數叫做散列函數,存放記錄的數組叫做散列表。
- 舉例:定義一個哈希表實現員工的增刪改查
package com.hashTab;
import java.util.Scanner;
/*
* 使用哈希表完成員工的增刪改查
*/
public class HashTabDemo2 {
public static void main(String[] args) {
// 創建哈希表
HashTab1 hashTab = new HashTab1(5);
// 寫一個簡單的菜單
String key = "";
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("add:添加僱員");
System.out.println("list:顯示僱員");
System.out.println("find:查找僱員");
System.out.println("delete:刪除僱員");
System.out.println("update:修改僱員信息");
System.out.println("exit:退出");
key = scanner.next();
switch (key) {
case "add":
System.out.println("請輸入用戶id");
int id = scanner.nextInt();
System.out.println("請輸入名字");
String name = scanner.next();
Employe emp = new Employe(id, name);
hashTab.add(emp);
break;
case "list":
hashTab.list();
break;
case "find":
System.out.println("請輸入要查找的id");
int findId = scanner.nextInt();
hashTab.findById(findId);
break;
case "delete":
System.out.println("請輸入僱員編號");
int deleteId = scanner.nextInt();
hashTab.deleteByID(deleteId);
break;
case "update":
System.out.println("請輸入僱員編號");
int updateId = scanner.nextInt();
System.out.println("請輸入僱員姓名");
String updateName = scanner.next();
hashTab.updateById(new Employe(updateId, updateName));
break;
case "exit":
scanner.close();
System.exit(0);
break;
default:
break;
}
}
}
}
//定義哈希表
class HashTab1 {
private EmployeLinkedList[] empLinkedListArray;
private int size;// 哈希表中鏈表的個數
public HashTab1(int size) {
this.size = size;
// 初始化鏈表數組
empLinkedListArray = new EmployeLinkedList[size];
// 數組中的每個鏈表也要創建,否則會報空指針
for (int i = 0; i < empLinkedListArray.length; i++) {
empLinkedListArray[i] = new EmployeLinkedList();
}
}
// 按取模的方式創建散列函數
public int hashFun(int id) {
return id % size;
}
// 添加員工
public void add(Employe emp) {
int i = hashFun(emp.getId());
empLinkedListArray[i].addById(emp);
}
// 遍歷哈希表
public void list() {
for (int i = 0; i < empLinkedListArray.length; i++) {
empLinkedListArray[i].list(i);
}
}
// 根據id查找員工
public void findById(int id) {
int i = hashFun(id);
Employe employe = empLinkedListArray[i].findById(id);
if (employe == null) {
System.out.printf("沒有找到編號爲%d的員工\n", id);
} else {
System.out.printf("編號爲%d的員工姓名是:%s\n", id, employe.getName());
}
}
// 根據id刪除員工
public void deleteByID(int id) {
int i = hashFun(id);
empLinkedListArray[i].deleteById(id, i);
}
// 根據id修改員工信息
public void updateById(Employe emp) {
int i = hashFun(emp.getId());
empLinkedListArray[i].updateById(emp, i);
}
}
//定義鏈表
class EmployeLinkedList {
private Employe head;// 頭節點
// 按id順序添加員工
public void addById(Employe emp) {
if (head == null) {// 第一次添加員工
head = emp;
return;
}
// 如果不是第一次添加,就先找到添加位置
Employe temp = head;
if (head.getId() > emp.getId()) {
head = emp;
head.setNext(temp);
return;
}
boolean flag = false;
while (true) {
if (temp.getNext() == null) {// 如果遍歷到最後,還沒找到,就在最後添加就行
break;
}
if (temp.getNext().getId() > emp.getId()) {// 如果temp的下一個節點的id大於要插入的id,那就在temp後面添加
flag = true;
break;
}
temp = temp.getNext();
}
if (flag) {
emp.setNext(temp.getNext());
temp.setNext(emp);
} else {
temp.setNext(emp);
}
}
// 遍歷鏈表
public void list(int i) {
if (head == null) {
System.out.printf("第%d鏈表爲空\n", i + 1);
return;
}
System.out.printf("第%d鏈表信息爲:", i + 1);
Employe temp = head;
while (true) {
System.out.printf("=> id=%d,name=%s\t", temp.getId(), temp.getName());
if (temp.getNext() == null) {
break;
}
temp = temp.getNext();
}
System.out.println();
}
// 根據id查找僱員
public Employe findById(int id) {
if (head == null) {
return null;
}
Employe temp = head;
while (true) {
if (temp.getId() == id) {
break;
}
if (temp.getNext() == null) {
temp = null;
break;
}
temp = temp.getNext();
}
return temp;
}
// 根據id刪除員工
public void deleteById(int id, int i) {
if (head == null) {
System.out.printf("第%d鏈表爲空,沒有編號爲%d的員工\n", i + 1, id);
return;
}
Employe temp = head;
if (head.getId() == id) {
head = head.getNext();
System.out.printf("編號爲%d的員工已刪除\n", id);
return;
}
boolean flag = false;
while (true) {
if (temp.getNext() == null) {
break;
}
if (temp.getNext().getId() == id) {
flag = true;
break;
}
temp = temp.getNext();
}
if (flag) {
temp.setNext(temp.getNext().getNext());
System.out.printf("編號爲%d的員工已刪除\n", id);
} else {
System.out.printf("沒有找到編號爲%d的員工\n", id);
}
}
// 根據id修改員工信息
public void updateById(Employe emp, int i) {
if (head == null) {
System.out.printf("第%d鏈表爲空,沒有編號爲%d的員工\n", i + 1, emp.getId());
return;
}
Employe temp = head;
if(head.getId()==emp.getId()) {
head.setName(emp.getName());
System.out.println("修改成功");
return;
}
boolean flag = false;
while (true) {
if (temp.getNext() == null) {
break;
}
if (temp.getId() == emp.getId()) {
flag = true;
break;
}
temp = temp.getNext();
}
if (flag) {
temp.setName(emp.getName());
System.out.println("修改成功");
} else {
System.out.printf("沒有編號爲%d的員工\n", emp.getId());
}
}
}
//定義員工類
class Employe {
private int id;// 員工編號
private String name;// 員工姓名
private Employe next;// 後指針
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Employe getNext() {
return next;
}
public void setNext(Employe next) {
this.next = next;
}
public Employe(int id, String name) {
super();
this.id = id;
this.name = name;
}
}