哈希表

根据尚硅谷的韩顺平老师的数据结构视频总结的笔记

观看视频的网址

 

一、哈希表(散列)-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 +
                '}';
    }
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值