根据尚硅谷的韩顺平老师的数据结构视频总结的笔记
一、哈希表(散列)-Google上机题
看一个实际需求,google公司的一个上机题:
有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,住址..),当输入该员工的id时,要求查找到该员工的 所有信息.
要求: 不使用数据库,尽量节省内存,速度越快越好=>哈希表(散列)
二、哈希表的基本介绍
散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
三、用哈希表实现google上机题
google公司的一个上机题:
有一个公司,当有新的员工来报道时,要求将该员工的信息加入 (id,性别,年龄,名字,住址..),当输入该员工的id时,要求查找到该员工的 所有信息.
要求:
1)不使用数据库,,速度越快越好=>哈希表(散列)
2)添加时,保证按照id从低到高插入
代码实现:
package hashTab;
/**
* @description: 用数组加链表实现 哈希表
* @auther:田坤
* @date 2020/10/11 20:09
**/
public class HashTabDemo {
public static void main(String[] args) {
HashTab hashTab = new HashTab(8);
//增加
for(int i = 1; i <= 20; i++){
hashTab.addEmp(new Emp(i,"田坤"+i));
}
//遍历
hashTab.list();
//查找
hashTab.findEmpById(15);
//删除
hashTab.deleteEmpById(16);
hashTab.list();
//修改
Emp emp = new Emp(6, "吴彦祖");
hashTab.updateEmp(emp);
hashTab.list();
}
}
//定义哈希表类 管理多条链表
class HashTab{
private EmpLinkedList[] EmpLinkedListArray;
private int size;
//构造器
public HashTab(int size){
this.size = size;
EmpLinkedListArray = new EmpLinkedList[size];
for (int i = 0; i < EmpLinkedListArray.length; i++) {
EmpLinkedListArray[i] = new EmpLinkedList();
}
}
//Add
public void addEmp(Emp emp){
int index = hashFun(emp.getNo());
EmpLinkedListArray[index].addEmp(emp);
}
//遍历
public void list(){
for(int i = 0 ; i < size ; i++){
EmpLinkedListArray[i].list();
System.out.println();
}
}
//Search
public void findEmpById(int no){
int index = hashFun(no);
Emp emp = EmpLinkedListArray[index].findEmpById(no);
if(emp != null){
System.out.println("你所查找的编号为:"+no+"的信息为:"+emp);
}else {
System.out.println("没有查到编号为:"+no+"的员工");
}
}
//根据员工ID删除
public void deleteEmpById(int no){
int index = hashFun(no);
boolean flag = EmpLinkedListArray[index].deleteEmpById(no);
if(flag)
System.out.println("删除成功!");
else
System.out.println("删除失败!");
}
//修改员工信息
public void updateEmp(Emp emp){
int index = hashFun(emp.getNo());
boolean flag = EmpLinkedListArray[index].updateEmp(emp);
if(flag)
System.out.println("修改成功!");
else
System.out.println("修改失败!");
}
//编写散列函数 使用 %
public int hashFun(int id){
try {
return id % size;
}catch (Exception e){
throw new RuntimeException(e.getMessage());
}
}
}
//定义一个雇员链表类(不带头节点的链表)
class EmpLinkedList{
private Emp head = null; //直接指向第一数据
//Add 默认加到链表尾部
public void addEmp(Emp emp){
Emp curEmp;
if(head == null)
head = emp;
else {
curEmp = head;
while (curEmp.getNext()!=null){
curEmp = curEmp.getNext();
}
curEmp.setNext(emp);
}
}
//根据员工ID查询
public Emp findEmpById(int no){
if(head == null )
return null;
Emp curEmp = head;
while (curEmp!=null){
if(curEmp.getNo() == no)
return curEmp;
curEmp = curEmp.getNext();
}
return null;
}
//根据员工ID删除
public boolean deleteEmpById(int no){
if(head == null)
return false;
Emp curEmp = head;
if(curEmp.getNo() == no) {
head.setNext(curEmp.getNext());
return true;
}
while (curEmp.getNext() != null){
if(curEmp.getNext().getNo() == no){
curEmp.setNext(curEmp.getNext().getNext());
return true;
}
curEmp = curEmp.getNext();
}
return false;
}
//修改员工信息
public boolean updateEmp(Emp emp){
if(head == null)
return false;
Emp curEmp = head;
while (curEmp != null){
if(curEmp.getNo() == emp.getNo()){
curEmp.setName(emp.getName());
return true;
}
curEmp = curEmp.getNext();
}
return false;
}
//遍历链表
public void list(){
Emp curEmp;
if(head == null)
System.out.println("链表为空");
else {
curEmp = head;
while (curEmp!= null){
System.out.print(curEmp.toString());
curEmp = curEmp.getNext();
}
}
}
}
//定义一个雇员类
class Emp{
private int no;
private String name;
private Emp next;
public Emp(){
}
public Emp(int no, String name) {
this.no = no;
this.name = name;
}
public int getNo() {
return no;
}
public Emp getNext() {
return next;
}
public void setNext(Emp next) {
this.next = next;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Emp{" +
"no=" + no +
", name='" + name + '\'' +
", next=" + next +
'}';
}
}