数据结构 - 哈希表

r囧r小猫 2023-07-08 15:24 214阅读 0赞

哈希表基本介绍

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

哈希表结构图:
在这里插入图片描述
下面我们用代码实现一个谷歌上机题:

看一个实际需求,google公司的一个上机题:
有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,住址…),当输入> > 该员工的id时,要求查找到该员工的 所有信息.
要求: 不使用数据库,尽量节省内存,速度越快越好=>哈希表(散列)

  • 下面代码我来代码实现

    package com.atguigu.hashtab;

    import java.util.Scanner;

    public class HashTabDemo {

    1. public static void main(String[] args) {
    2. //创建哈希表
    3. HashTab hashTab = new HashTab(7);
    4. //写一个简单的菜单
    5. String key = "";
    6. Scanner scanner = new Scanner(System.in);
    7. while(true) {
    8. System.out.println("add: 添加雇员");
    9. System.out.println("list: 显示雇员");
    10. System.out.println("find: 查找雇员");
    11. System.out.println("exit: 退出系统");
    12. key = scanner.next();
    13. switch (key) {
    14. case "add":
    15. System.out.println("输入id");
    16. int id = scanner.nextInt();
    17. System.out.println("输入名字");
    18. String name = scanner.next();
    19. //创建 雇员
    20. Emp emp = new Emp(id, name);
    21. hashTab.add(emp);
    22. break;
    23. case "list":
    24. hashTab.list();
    25. break;
    26. case "find":
    27. System.out.println("请输入要查找的id");
    28. id = scanner.nextInt();
    29. hashTab.findEmpById(id);
    30. break;
    31. case "exit":
    32. scanner.close();
    33. System.exit(0);
    34. default:
    35. break;
    36. }
    37. }
    38. }

    }

    //创建HashTab 管理多条链表
    class HashTab {

    1. private EmpLinkedList[] empLinkedListArray;
    2. private int size; //表示有多少条链表
    3. //构造器
    4. public HashTab(int size) {
    5. this.size = size;
    6. //初始化empLinkedListArray
    7. empLinkedListArray = new EmpLinkedList[size];
    8. //?留一个坑, 这时不要分别初始化每个链表
    9. for(int i = 0; i < size; i++) {
    10. empLinkedListArray[i] = new EmpLinkedList();
    11. }
    12. }
    13. //添加雇员
    14. public void add(Emp emp) {
    15. //根据员工的id ,得到该员工应当添加到哪条链表
    16. int empLinkedListNO = hashFun(emp.id);
    17. //将emp 添加到对应的链表中
    18. empLinkedListArray[empLinkedListNO].add(emp);
    19. }
    20. //遍历所有的链表,遍历hashtab
    21. public void list() {
    22. for(int i = 0; i < size; i++) {
    23. empLinkedListArray[i].list(i);
    24. }
    25. }
    26. //根据输入的id,查找雇员
    27. public void findEmpById(int id) {
    28. //使用散列函数确定到哪条链表查找
    29. int empLinkedListNO = hashFun(id);
    30. Emp emp = empLinkedListArray[empLinkedListNO].findEmpById(id);
    31. if(emp != null) { //找到
    32. System.out.printf("在第%d条链表中找到 雇员 id = %d\n", (empLinkedListNO + 1), id);
    33. }else{
    34. System.out.println("在哈希表中,没有找到该雇员~");
    35. }
    36. }
    37. //编写散列函数, 使用一个简单取模法
    38. public int hashFun(int id) {
    39. return id % size;
    40. }
  1. }
  2. //表示一个雇员
  3. class Emp {
  4. public int id;
  5. public String name;
  6. public Emp next; //next 默认为 null
  7. public Emp(int id, String name) {
  8. super();
  9. this.id = id;
  10. this.name = name;
  11. }
  12. }
  13. //创建EmpLinkedList ,表示链表
  14. class EmpLinkedList {
  15. //头指针,执行第一个Emp,因此我们这个链表的head 是直接指向第一个Emp
  16. private Emp head; //默认null
  17. //添加雇员到链表
  18. //说明
  19. //1. 假定,当添加雇员时,id 是自增长,即id的分配总是从小到大
  20. // 因此我们将该雇员直接加入到本链表的最后即可
  21. public void add(Emp emp) {
  22. //如果是添加第一个雇员
  23. if(head == null) {
  24. head = emp;
  25. return;
  26. }
  27. //如果不是第一个雇员,则使用一个辅助的指针,帮助定位到最后
  28. Emp curEmp = head;
  29. while(true) {
  30. if(curEmp.next == null) { //说明到链表最后
  31. break;
  32. }
  33. curEmp = curEmp.next; //后移
  34. }
  35. //退出时直接将emp 加入链表
  36. curEmp.next = emp;
  37. }
  38. //遍历链表的雇员信息
  39. public void list(int no) {
  40. if(head == null) { //说明链表为空
  41. System.out.println("第 "+(no+1)+" 链表为空");
  42. return;
  43. }
  44. System.out.print("第 "+(no+1)+" 链表的信息为");
  45. Emp curEmp = head; //辅助指针
  46. while(true) {
  47. System.out.printf(" => id=%d name=%s\t", curEmp.id, curEmp.name);
  48. if(curEmp.next == null) { //说明curEmp已经是最后结点
  49. break;
  50. }
  51. curEmp = curEmp.next; //后移,遍历
  52. }
  53. System.out.println();
  54. }
  55. //根据id查找雇员
  56. //如果查找到,就返回Emp, 如果没有找到,就返回null
  57. public Emp findEmpById(int id) {
  58. //判断链表是否为空
  59. if(head == null) {
  60. System.out.println("链表为空");
  61. return null;
  62. }
  63. //辅助指针
  64. Emp curEmp = head;
  65. while(true) {
  66. if(curEmp.id == id) { //找到
  67. break;//这时curEmp就指向要查找的雇员
  68. }
  69. //退出
  70. if(curEmp.next == null) { //说明遍历当前链表没有找到该雇员
  71. curEmp = null;
  72. break;
  73. }
  74. curEmp = curEmp.next;//以后
  75. }
  76. return curEmp;
  77. }
  78. }

发表评论

表情:
评论列表 (有 0 条评论,214人围观)

还没有评论,来说两句吧...

相关阅读

    相关 数据结构 -

    哈希表基本介绍 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访

    相关 数据结构——

    1、基础知识 1.1 引子 在实现编程中,常常面临着两个问题:存储和查询。存储和查询的效率往往决定了整个程序的效率。而我们常见存储数据的数据结构比如线性表,树等。数