哈希表

哈希表基本介绍

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

 

  • 哈希表的应用场景:

      

 

  • 哈希表的逻辑图: 

        

有关哈希表的一个例题

有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,名字,住址..),当输入该员工的id 时, 要求查找到该员工的所有信息。
  要求:
    1) 不使用数据库,,速度越快越好=>哈希表(散列)
    2) 添加时,保证按照 id 从低到高插入
      [思考题:如果 id 不是从低到高插入,但要求各条链表仍是从低到高,怎么解决?]
    3) 使用链表来实现哈希表, 该链表不带表头[即: 链表的第一个结点就存放雇员信息]
    4) 思路分析并画出示意图

代码实现

Employee类

 1 class Employee {
 2     private int id;
 3     private String name;
 4     private Employee next; //next 默认为 null
 5 
 6     public Employee() {
 7         this.id=0;
 8         this.name=null;
 9     }
10 
11     public int getId() {
12         return id;
13     }
14 
15     public void setId(int id) {
16         this.id = id;
17     }
18 
19     public String getName() {
20         return name;
21     }
22 
23     public void setName(String name) {
24         this.name = name;
25     }
26 
27     public Employee getNext() {
28         return next;
29     }
30 
31     public void setNext(Employee next) {
32         this.next = next;
33     }
34 
35     public Employee(int id, String name) {
36         this.id = id;
37         this.name = name;
38     }
39 
40     @Override
41     public String toString() {
42         return "employee{" +
43                 "id=" + id +
44                 ", name='" + name + '\'' +
45                 '}';
46     }
47 }

EmpLinkedList类

 1 class EmpLinkedList {
 2     //头指针,执行第一个 Emp,因此我们这个链表的 head 是直接指向第一个 Emp
 3     private Employee head;//默认 null
 4 
 5     //添加雇员到链表
 6     //说明
 7     //1. 假定,当添加雇员时,id 是自增长,即 id 的分配总是从小到大
 8     //    因此我们将该雇员直接加入到本链表的最后即可
 9     public void add(Employee emp) {
10         if (head == null) {
11             head = emp;
12         } else {
13             Employee temp = head;
14             while (temp.getNext() != null) {
15                 temp = temp.getNext();
16             }
17             temp.setNext(emp);
18         }
19     }
20 
21     public void list() {
22         if (head == null) {
23             System.out.println("linked list():链表为空。。。。");
24             return;
25         }
26         Employee temp = head;
27         while (true) {
28             if (temp.getNext() == null) {
29             } else {
30                 System.out.print(temp + "==>");
31 
32             }
33             if (temp.getNext() == null) {//说明 curEmp 已经是最后结点
34                 break;
35             }
36             temp = temp.getNext();
37         }
38         System.out.println();
39     }
40 
41     public Employee delete(int id) {
42         if (head == null) {
43             System.out.println("linked findEmp():链表为空。。。。");
44             return null;
45         }
46         Employee temp = head;
47         while (true) {
48             if (temp.getId() == id) {
49                 System.out.println("linked delete():删除成功!");
50                 return temp;
51             }
52             if (temp.getNext() == null) {
53                 System.out.println("linked delete():查无此人。。。。。");
54                 return null;
55             }
56             temp = temp.getNext();
57         }
58     }
59 
60     //根据 id 查找雇员
61     public void findEmp(int id) {
62         if (head == null) {
63             System.out.println("linked findEmp():链表为空。。。。");
64             return;
65         }
66         Employee temp = head;
67         while (true) {
68             if (temp.getId() == id) {
69                 System.out.println("linked findEmp():id为 " + id + " 的人员信息为:" + temp);
70                 break;
71             }
72             if (temp.getNext() == null) {
73                 System.out.println("linked findEmp():查无此人。。。。。");
74                 break;
75             }
76             temp = temp.getNext();
77         }
78     }
79 }

HashTableDemo类

  1 public class HashTableDemo {
  2     public static void main(String[] args) {
  3         //创建哈希表
  4         HashTable hashTab = new HashTable(7);
  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 
 13             String key = scanner.next();
 14             switch (key) {
 15                 case "add":
 16                     System.out.println("输入 id");
 17                     int id = scanner.nextInt();
 18                     System.out.println("输入名字");
 19                     String name = scanner.next();
 20                     //创建 雇员
 21                     Employee emp = new Employee(id, name);
 22                     hashTab.add(emp);
 23                     break;
 24                 case "list":
 25                     hashTab.list();
 26                     break;
 27                 case "find":
 28                     System.out.println("请输入要查找的 id");
 29                     id = scanner.nextInt();
 30                     hashTab.findEmp(id);
 31                     break;
 32                 case "exit":
 33                     scanner.close();
 34                     System.exit(0);
 35                 default:
 36                     break;
 37             }
 38         }
 39     }
 40 
 41 }
 42 
 43 //创建 HashTab 管理多条链表
 44 class HashTable {
 45     private EmpLinkedList[] empLinkedListArray;
 46     private int size ;//定义数组长度,表示有多少条链表
 47 
 48     //构造器
 49     public HashTable(int size) {
 50         this.size = size;
 51         empLinkedListArray = new EmpLinkedList[size];//初始化 empLinkedListArray
 52         //避坑!! 这时必须要分别初始化每个链表
 53         for (int i = 0; i < empLinkedListArray.length; i++) {
 54             empLinkedListArray[i] = new EmpLinkedList();
 55         }
 56     }
 57 
 58     //添加雇员
 59     public void add(Employee emp) {
 60         int hashfun = this.hashfun(emp.getId());//根据员工的 id ,得到该员工应当添加到哪条链表
 61         empLinkedListArray[hashfun].add(emp);//将 emp 添加到对应的链表中
 62     }
 63 
 64     //遍历所有的链表,遍历 hashtab
 65     public void list() {
 66         for (int i = 0; i < empLinkedListArray.length; i++) {
 67             System.out.print("第" + i + "条链表:");
 68             empLinkedListArray[i].list();
 69         }
 70     }
 71 
 72     //根据输入的 id,删除雇员
 73     public Employee delete(int id) {
 74         int hashfun = this.hashfun(id);
 75         Employee delete = empLinkedListArray[hashfun].delete(id);
 76         return delete;
 77     }
 78 
 79     //根据输入的 id,查找雇员
 80     public void findEmp(int id) {
 81         int hashfun = this.hashfun(id);
 82         empLinkedListArray[hashfun].findEmp(id);
 83     }
 84 
 85     //编写散列函数, 使用一个简单取模法
 86     public int hashfun(int id) {
 87         return id % size;
 88     }
 89 
 90     @Override
 91     public boolean equals(Object o) {
 92         if (this == o) return true;
 93         if (o == null || getClass() != o.getClass()) return false;
 94         HashTable hashtable = (HashTable) o;
 95         return size == hashtable.size &&
 96                 Arrays.equals(empLinkedListArray, hashtable.empLinkedListArray);
 97     }
 98 
 99     @Override
100     public int hashCode() {
101         int result = Objects.hash(size);
102         result = 31 * result + Arrays.hashCode(empLinkedListArray);
103         return result;
104     }
105 }

 

posted @ 2020-11-03 11:32  白刃天使  阅读(168)  评论(0编辑  收藏  举报