2020-08-30

哈希表:

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

实现方式有:数组+链表(每次放入数据时都要哈希一下,提高速率)
					  数组+二叉树

在这里插入图片描述

哈希表可以作为中间缓存,把一些暂且不须放在数据库的数据放在中间缓存区上进行对应的处理。

实现方式:

package com.java;

import javax.swing.plaf.nimbus.AbstractRegionPainter;
import java.util.HashMap;
import java.util.Scanner;

public class HashTableDemo {
    public static void main(String[] args) {
        HashTable hashTable = new HashTable(7);
        boolean loop = true;
        Scanner scanner = new Scanner(System.in);
        String key = "";
        while (loop)
        {
            System.out.println("add--------->添加员工");
            System.out.println("addByOrder-->添加员工");
            System.out.println("list-------->遍历员工");
            System.out.println("find-------->查找员工");
            System.out.println("exit-------->退出程序");

            key = scanner.next();
            switch (key)
            {
                case "add":
                    System.out.println("输入需要添加员工的id以及姓名");
                    int id_add = scanner.nextInt();
                    String name = scanner.next();
                    Emp emp = new Emp(id_add, name);
                    hashTable.add(emp);
                    break;
                case "addByOrder":
                    System.out.println("输入需要添加员工的id以及姓名");
                    int id_addBy = scanner.nextInt();
                    String nameBy = scanner.next();
                    Emp empBy = new Emp(id_addBy, nameBy);
                    hashTable.addById(empBy);
                    break;
                case "list":
                    hashTable.list();
                    break;
                case "find":
                    System.out.println("请输入要查找员工id的值");
                    int id_find = scanner.nextInt();
                    hashTable.findEmpById(id_find);
                    break;
                case "exit":
                    loop = false;
                    scanner.close();
                    break;
                default:
                    break;
            }
        }
    }
}

//创建一个哈希表
class HashTable
{
    private EmpLinkedList[] empLinkedList;
    private int size;//定义链表的数量

    public HashTable(int size) {
        this.size = size;
        //初始化
        empLinkedList = new EmpLinkedList[size];
        for (int i = 0; i < size; i++) {
        empLinkedList[i] = new EmpLinkedList();
        }
    }
    //添加雇员
    public void add(Emp emp)
    {
        //根据员工的id,得到员工应当添加链表的位置
        int empLinkedListNo = hasFun(emp.id);
        //将emp添加到对应的链表中
        empLinkedList[empLinkedListNo].add(emp);
    }

    //根据指定id添加雇员
    public void addById(Emp emp)
    {
        //根据员工的id,得到员工应当添加链表的位置
        int empLinkedListNo = hasFun(emp.id);
        //将emp添加到对应的链表中
        empLinkedList[empLinkedListNo].addById(emp);
    }

    //遍历链表
    public void list()
    {
        for (int i = 0; i < size; i++) {
            empLinkedList[i].list(i);
        }
    }

    //根据用户输入的id查找员工
    public void findEmpById(int id)
    {
        int empLinkedListId = hasFun(id);
        Emp emp = empLinkedList[empLinkedListId].findEmpByid(id);
        if (emp != null)//说明此时已找到
        {
            System.out.println("在第" + (empLinkedListId + 1) + "条链表上找到员工,员工id为:" + id);
        }else
        {
            System.out.println("在哈希表上没有找到该员工!··");
        }

    }



    //编写散列函数的简单取模法
    public int hasFun(int id)
    {
        return id % size;
    }
}


//创建一个链表,实现对应的添删改查功能
class EmpLinkedList
{
    private Emp head = null;//定义头结点为空

    //添加员工,此时是根据id是自增长添加
    public void add(Emp emp)
    {
        //当头结点为空时,赋值
        if (head == null)
        {
            head = emp;
            return;
        }
        //当头结点不为空时,定义一个辅助指针遍历到链表最后,然而再添加
        Emp cur = head;
        while (true)
        {
            if (cur.next == null)break;
            cur = cur.next;
        }
        //此时位置已找到
        cur.next = emp;
    }

    //根据指定id添加员工信息
    public void addById(Emp emp)
    {
        if (head == null)
        {
            head = emp;
            return;
        }
        boolean flag = false;//定义一个标记,看此时添加的数据是否存在单链表中
        Emp cur = head;//定义一个辅助指针
        while (true)
        {
            if (cur.next == null)
                break;//此时找到最后一个链表,退出循环
            else if (cur.next.id == emp.id)//此时需添加的节点已存在
            {
                flag = true;
                break;
            }else if (cur.next.id > emp.id)break;//此时已找到
            cur = cur.next;

        }
        //退出循环后添加数据
        if (flag)
        {
            System.out.println("需要添加id为:" + emp.id + "已经存在");
        }else
        {
            emp.next = cur.next;
            cur.next = emp;
        }

    }

    //遍历员工信息表
    public void list(int no)
    {
        //判断链表是否为空
        if (head == null){
            System.out.println("第"+ (no + 1) + "链表为空!");
            return;
        }
        //定义一个辅助指针cur
        Emp cur = head;
        System.out.print("第"+(no + 1)+"链表的信息为:");
        while (true)
        {
            System.out.print("id = " + cur.id + "=>" + "name = " + cur.name + "\t");
            if (cur.next == null)break;//此时遍历完毕,退出循环
            cur = cur.next;
        }
        System.out.println();
    }

    //根据指点id查找员工信息
    public Emp findEmpByid(int id) {
        //判断链表是否为空
        if (head == null) {
            System.out.println("链表为空");
            return null;
        }
        //定义一个辅助变量指针
        Emp cur = head;
        while (true)
        {
            if (cur.id == id)
            {
                break;//此时已找到,退出
            }
            if (cur.next == null) {
                cur = null;
                break;//此时遍历完毕
            }
            cur = cur.next;//后移
        }
        return cur;
    }
}

//定义一个Emp类,存放员工id、姓名、next指针
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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值