大家好,我是皮皮猫吖!
每文一言:别否定自己,你特别好,特别温柔,特别值得。
本篇文章:
主要是关于java数据结构与算法的一些基本知识:哈希表。
正文如下:
一、哈希表
1)哈希表的面试题
有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,住址…),当输入该员工的id时,要求查找到该员工的所有信息。
要求: 不使用数据库,尽量节省内存,速度越快越好 ==> 哈希表(散列)
2)散列表
散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
简单的散列函数 (简单取余):长度为15的散列表,把id为111的放入到该散列表中,将111进行 % 15的操作,将111放到 111%15的这个链表中
3)哈希表相关的面试题:
① 问题:
有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,名字,住址…),当输入该员工的id时,要求查找到该员工的所有信息。
② 要求:
1)不使用数据库的前提下,速度越快越好 ==> 选择使用哈希表(散列)
2)添加数据的时候,保证按照id从低到高插入 == 插入数据的时候,进行排序
3)使用链表来实现哈希表, 该链表不带表头[即: 链表的第一个结点就存放雇员信息]
4)代码实现[简单的增删改查(显示所有员工,按id查询)]
③ 代码如下:
package com.immort.dataStructure.hash;
import java.util.Objects;
import java.util.Scanner;
/**
* 哈希表的相关代码
* @author ppmy
* @create 2021-04-03 18:09
*/
public class Study1HashTableDemo1 {
public static void main(String[] args) {
menu();
}
//菜单
private static void menu(){
HashTable hashTable = new HashTable(7);
Scanner scanner = new Scanner(System.in);
String key = "";
int id;
String name;
Emp emp;
while (true){
System.out.println("add :添加数据");
System.out.println("list:遍历链表");
System.out.println("exit:退出程序");
System.out.println("get :获取数据");
System.out.println("del :删除数据");
key = scanner.next();
switch (key){
case "add":
System.out.print("请输入id:");
id = scanner.nextInt();
System.out.print("请输入名字:");
name = scanner.next();
emp = new Emp(id, name,null);
hashTable.addEmp(emp);
break;
case "list":
System.out.println("遍历当前哈希表:");
hashTable.listAll();
break;
case "exit":
return;
case "get":
System.out.print("请输入要获取数据的id:");
int idName = scanner.nextInt();
Emp emp1 = hashTable.getEmp(idName);
if(emp1!=null){
System.out.println(emp1);
}else{
System.out.println("该id数据不存在!");
}
break;
case "del":
System.out.print("请输入要删除的数据id:");
id = scanner.nextInt();
boolean b = hashTable.deleteEmp(id);
if (b){
System.out.println("id为"+(id)+"的数据删除成功!");
}else{
System.out.println("该数据不在哈希表中,删除失败!");
}
}
}
}
}
//存放EmpLinkedList的哈希表
//哈希表:存储多条链表
class HashTable{
//哈希表
private EmpLinkedList[] empLinkedListArr;
//哈希表的大小:存放多少个链表
private int size;
//构造器:哈希表:存放size个链表
public HashTable(int size){
this.size = size;
//创建一个size大小的哈希表
empLinkedListArr = new EmpLinkedList[size];
//创建每一个链表的头节点
for (int i = 0; i < size; i++){
empLinkedListArr[i] = new EmpLinkedList();
}
}
//向对应的链表中添加数据
public void addEmp(Emp emp){
//根据员工的id,获取到该员工应该加入到哪一条链表
int empLinkedListNum = hashFun(emp.getId());
//将emp数据放到对应的链表中
empLinkedListArr[empLinkedListNum].addEmp(emp);
}
//遍历所有的链表
public void listAll(){
for (int i = 0; i < empLinkedListArr.length;i++){
//遍历当前链表中的数据,如果返回值为false
if(!empLinkedListArr[i].listEmp(i)){
System.out.println((i+1)+"链表为空!");
}
}
}
//编写一个散列函数
private int hashFun(int id){
return id % size;
}
public Emp getEmp(int id){
return empLinkedListArr[id%size].getEmp(id);
}
//通过id删除数据
public boolean deleteEmp(int id){
return empLinkedListArr[id%size].deleteEmp(id);
}
}
//存放emp的链表
class EmpLinkedList{
private Emp head;
public EmpLinkedList() {
}
public Emp getHead() {
return head;
}
public void setHead(Emp head) {
this.head = head;
}
//添加数据到链表中
public void addEmp(Emp emp){
//如果当前的head节点为null,表示链表为空,将当前节点置为头结点
if(head==null){
//将该节点置为头结点
head = emp;
}
else{
//获取到头结点
Emp current = head;
//遍历当前链表,遍历到按序排列的位置,添加数据
while (current.getNext()!=null){
if(current.getNext().getId()>emp.getId()){
emp.setNext(current.getNext());
current.setNext(emp);
return;
}
current = current.getNext();
}
if(current==head){
if(current.getId()>emp.getId()){
emp.setNext(current);
head = emp;
return;
}
}
//节点添加到当前链表的末尾处
current.setNext(emp);
}
}
//遍历当前链表
public boolean listEmp(int i){
//获取到头结点
Emp current = head;
//如果当前头结点为null,直接返回false
if(current==null){
return false;
}
//当前链表数据不为空
//遍历当前链表
System.out.println((i+1)+"链表的信息为:");
while (current!=null){
System.out.println(current);
current = current.getNext();
}
return true;
}
//根据id查找指定Emp数据
public Emp getEmp(int id){
Emp current = head;
while (current!=null){
if(current.getId()==id){
return current;
}
current = current.getNext();
}
return null;
}
//通过id删除emp数据
public boolean deleteEmp(int id){
Emp current = head;
if(current==null){
return false;
}
while (current!=null && current.getId()!=id){
current = current.getNext();
}
if(current==head){
head = current.getNext();
return true;
}
return false;
}
}
//emp数据
class Emp{
private int id;
private String name;
//指向下一个emp节点
private Emp next;
public Emp() {
}
public Emp(int id, String name,Emp next) {
this.id = id;
this.name = name;
this.next = 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 void setNext(Emp next){
this.next = next;
}
public Emp getNext(){
return this.next;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Emp emp = (Emp) o;
return id == emp.id && Objects.equals(name, emp.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
@Override
public String toString() {
return "Emp{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
希望本篇文章对大家有所帮助,后续会继续分享java数据结构与算法相关学习知识…
如果文章内容有错误的地方,请在留言处留下你的见解,方便大家共同学习。谢谢!
如有侵权或其他任何问题请联系:QQ1370922071,本文主要用于学习交流,转载请声明!
作者:皮皮猫吖