算法基础12:哈希表

哈希表是一个数据结构,不是算法

看一个实际需求,google公司的一个上机题:

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

基本介绍

练习

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
import java.util.Scanner;

/**
* 哈希表
*
* @author:XMD
* @date: 5.9.22
*/
public class HashTabDemo {

public static void main(String[] args) {
HashTab hashTab = new HashTab(7);
String key = "";
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("add:添加雇员");
System.out.println("list:显示雇员");
System.out.println("find:查找雇员");
System.out.println("exit:退出系统");
key = scanner.next();
switch (key) {
case "add":
System.out.println("输入ID");
int anInt = scanner.nextInt();
System.out.println("输入名字");
String next = scanner.next();
Emp emp = new Emp(anInt, next);
hashTab.add(emp);
break;
case "list":
hashTab.list();
break;
case "find":
System.out.println("输入查找的ID");
int fid = scanner.nextInt();
hashTab.findEmpById(fid);
break;
case "exit":
scanner.close();
System.exit(0);
default:
break;
}

}
}
}


class HashTab {
private EmpLinkedList[] empLinkedListArray;
//链表个数
public int size;

public HashTab(int size) {
this.size = size;
this.empLinkedListArray = new EmpLinkedList[size];
//分别初始化每个链表
for (int i = 0; i < size; i++) {
empLinkedListArray[i] = new EmpLinkedList();
}

}

public void add(Emp emp) {
//根据员工的id,得到该员工应当添加到哪条链表
int empLinkedListNo = hashFun(emp.id);
//将emp添加到对应的链表中
empLinkedListArray[empLinkedListNo].add(emp);
}

//遍历所有的链表,遍历hashtab
public void list() {
for (int i = 0; i < size; i++) {
empLinkedListArray[i].list(i);
}
}

public void findEmpById(int id) {
int fun = hashFun(id);
Emp emp = empLinkedListArray[fun].findEmpById(id);
if (emp != null) {
System.out.println(emp.id + ">>" + emp.name);
} else {
System.out.println("没有找到");
}
}


public int hashFun(int id) {
return id % size;
}
}


class Emp {
public int id;
public String name;
//默认为空
public Emp next;

public Emp(int id, String name) {
this.id = id;
this.name = name;
}
}

//创建EmpLinkedList,表示链表
class EmpLinkedList {
//头指针,执行第一个Emp,因此我们这个链表的head是直接指向第一个mp
public Emp head;

//添加雇员到链表
//说明
//1,假定,当添加雇员时,id是自增长,即id的分配总是从小到大
//因此我们将该雇员直接加入到本链表的最后即可
public void add(Emp emp) {
//如果是添加第一个雇员
if (head == null) {
head = emp;
return;
}
//如果不是第一个雇员,则使用一个辅助的指针,帮助定位到最后
Emp curEmp = head;
while (true) {
if (curEmp.next == null) {
break;
}
curEmp = curEmp.next;
}
//退出时直接将emp加入链表
curEmp.next = emp;
}


//遍历链表的雇员信息
public void list(int no) {
if (head == null) {
System.out.println(no + "个链表为空");
return;
}
Emp curEmp = head;
while (true) {
System.out.println(no + "--id = " + curEmp.id);
if (curEmp.next == null) {
//说明curEmp已经是最后结点
return;
}
curEmp = curEmp.next;
}
}

//如果查找到,就返回Emp,如果没有找到,就返回nul1
public Emp findEmpById(int id) {
if (head == null) {
System.out.println("链表为空");
return null;
}
Emp curEmp = head;
while (true) {
if (curEmp.id == id) {
//说明curEmp已经是最后结点
break;
}
if (curEmp.next == null) {
//说明curEmp已经是最后结点
curEmp = null;
}
curEmp = curEmp.next;
}
return curEmp;
}

}

-------------本文结束感谢您的阅读-------------