哈希表

哈希表:

哈希表又称散列表,结构为数组加链表,通过计算数据的哈希值能够准确知道这个数据在哪条链表上,加快查找速度(自己写的,可能不太准确)。

例子:

有一个公司,当有新的员工来报道时,要求将该员工的信息(编号,名字)加入,然后可以对这个员工进行增删改查,要求使用哈希表。

代码:

复制代码
  1 import lombok.Data;
  2 import lombok.NoArgsConstructor;
  3 import java.util.Scanner;
  4 
  5 public class HashTableTest {
  6     public static void main(String[] args) {
  7         //创建哈希表
  8         HashTable hashTab = new HashTable(7);
  9         //写一个简单的菜单
 10         String key = "";
 11         Scanner scanner = new Scanner(System.in);
 12         while(true) {
 13             System.out.println("add:  添加雇员");
 14             System.out.println("delete:  删除雇员");
 15             System.out.println("update:  修改雇员");
 16             System.out.println("find: 查找雇员");
 17             System.out.println("list: 显示雇员");
 18             System.out.println("exit: 退出系统");
 19 
 20             key = scanner.next();
 21             switch (key) {
 22                 case "add":
 23                     System.out.println("输入编号");
 24                     int no = scanner.nextInt();
 25                     System.out.println("输入名字");
 26                     String name = scanner.next();
 27                     //创建 雇员
 28                     EmpNode emp = new EmpNode(no, name);
 29                     boolean addBoo = hashTab.add(emp);
 30                     if (addBoo) {
 31                         System.out.println("~~~添加成功~~~");
 32                     } else {
 33                         System.out.println("~~~添加失败~~~");
 34                     }
 35                     break;
 36                 case "delete":
 37                     System.out.println("输入编号");
 38                     no = scanner.nextInt();
 39                     boolean deleteBoo = hashTab.delete(no);
 40                     if (deleteBoo) {
 41                         System.out.println("~~~删除成功~~~");
 42                     } else {
 43                         System.out.println("~~~删除失败~~~");
 44                     }
 45                     break;
 46                 case "update":
 47                     System.out.println("输入编号");
 48                     no = scanner.nextInt();
 49                     System.out.println("输入名字");
 50                     name = scanner.next();
 51                     //创建 雇员
 52                     emp = new EmpNode(no, name);
 53                     boolean updateBoo = hashTab.update(emp);
 54                     if (updateBoo) {
 55                         System.out.println("~~~更新成功~~~");
 56                     } else {
 57                         System.out.println("~~~更新失败~~~");
 58                     }
 59                     break;
 60                 case "find":
 61                     System.out.println("请输入要查找的编号");
 62                     no = scanner.nextInt();
 63                     EmpNode empNode = hashTab.find(no);
 64                     if (empNode == null) {
 65                         System.out.println("~~~没有找到~~~");
 66                     } else {
 67                         System.out.println(empNode);
 68                     }
 69                     break;
 70                 case "list":
 71                     hashTab.list();
 72                     break;
 73                 case "exit":
 74                     scanner.close();
 75                     System.exit(0);
 76                 default:
 77                     break;
 78             }
 79         }
 80     }
 81 }
 82 
 83 /**
 84  * 员工节点
 85  */
 86 @Data
 87 @NoArgsConstructor
 88 class EmpNode {
 89 
 90     /**
 91      * 员工编号
 92      */
 93     private int empNo;
 94 
 95     /**
 96      * 员工名称
 97      */
 98     private String empName;
 99 
100     private EmpNode next;
101 
102     public EmpNode(int empNo, String empName) {
103         this.empNo = empNo;
104         this.empName = empName;
105     }
106 
107     @Override
108     public String toString() {
109         return "EmpNode{" +
110                 "empNo=" + empNo +
111                 ", empName=" + empName +
112                 '}';
113     }
114 }
115 
116 /**
117  * 单链表
118  */
119 @NoArgsConstructor
120 class EmpLinkedList {
121 
122     /**
123      * 头节点
124      */
125     private EmpNode headNode;
126 
127     /**
128      * 是否为空
129      * @return
130      */
131     public boolean isEmpty() {
132         return headNode == null;
133     }
134 
135     /**
136      * 添加
137      * @param empNode
138      * @return
139      */
140     public boolean add(EmpNode empNode) {
141         if (isEmpty()) {
142             //添加第一个元素
143             headNode = empNode;
144             return true;
145         }
146         //按编号顺序添加
147         if (empNode.getEmpNo() < headNode.getEmpNo()) {
148             //新的节点作为头节点
149             empNode.setNext(headNode);
150             headNode = empNode;
151             return true;
152         } else if (empNode.getEmpNo() == headNode.getEmpNo()) {
153             return false;
154         }
155         EmpNode temp = headNode;
156         while (temp.getNext() != null) {
157             if (empNode.getEmpNo() < temp.getNext().getEmpNo()) {
158                 empNode.setNext(temp.getNext());
159                 temp.setNext(empNode);
160                 return true;
161             } else if (empNode.getEmpNo() == temp.getNext().getEmpNo()) {
162                 return false;
163             }
164             temp = temp.getNext();
165         }
166         temp.setNext(empNode);
167         return true;
168     }
169 
170     /**
171      * 删除
172      * @param empNo
173      * @return
174      */
175     public boolean delete(int empNo) {
176         if (isEmpty()) {
177             return false;
178         }
179 
180         if (headNode.getEmpNo() == empNo) {
181             //删除当前的头节点
182             headNode = headNode.getNext();
183             return true;
184         } else if (headNode.getEmpNo() > empNo) {
185             return false;
186         }
187         EmpNode temp = headNode;
188         while (temp.getNext() != null) {
189             if (temp.getNext().getEmpNo() == empNo) {
190                 temp.setNext(temp.getNext().getNext());
191                 return true;
192             } else if (temp.getNext().getEmpNo() > empNo) {
193                 return false;
194             }
195             temp = temp.getNext();
196         }
197         return false;
198     }
199 
200     /**
201      * 更新
202      * @param empNode
203      * @return
204      */
205     public boolean update(EmpNode empNode) {
206         if (isEmpty()) {
207             return false;
208         }
209         EmpNode temp = headNode;
210         while (temp != null) {
211             if (temp.getEmpNo() == empNode.getEmpNo()) {
212                 temp.setEmpName(empNode.getEmpName());
213                 return true;
214             } else if (temp.getEmpNo() > empNode.getEmpNo()) {
215                 return false;
216             }
217             temp = temp.getNext();
218         }
219         return false;
220     }
221 
222     /**
223      * 查找
224      * @param empNo
225      * @return
226      */
227     public EmpNode find(int empNo) {
228         if (isEmpty()) {
229             return null;
230         }
231         EmpNode temp = headNode;
232         while (temp != null) {
233             if (temp.getEmpNo() == empNo) {
234                 return temp;
235             } else if (temp.getEmpNo() > empNo) {
236                 return null;
237             }
238             temp = temp.getNext();
239         }
240         return null;
241     }
242 
243     @Override
244     public String toString() {
245         if (isEmpty()) {
246             return "->链表为空";
247         }
248         EmpNode temp = headNode;
249         StringBuilder strBu = new StringBuilder();
250         while (temp != null) {
251             strBu.append("->{no:" + temp.getEmpNo() + ",name:" + temp.getEmpName() + "}");
252             temp = temp.getNext();
253         }
254         return strBu.toString();
255     }
256 }
257 
258 class HashTable {
259     /**
260      * 链表数组
261      */
262     private EmpLinkedList[] empLinkedListArr;
263 
264     /**
265      * 链表数组的长度
266      */
267     private int size;
268 
269     public HashTable(int size) {
270         this.size = size;
271         empLinkedListArr = new EmpLinkedList[size];
272         for (int i = 0; i < empLinkedListArr.length; i++) {
273             empLinkedListArr[i] = new EmpLinkedList();
274         }
275     }
276 
277     /**
278      * 计算哈希值
279      * @param no
280      * @return
281      */
282     private int hashValue(int no) {
283         return no % size;
284     }
285 
286     /**
287      * 添加
288      * @param empNode
289      * @return
290      */
291     public boolean add(EmpNode empNode) {
292         int hashValue = hashValue(empNode.getEmpNo());
293         //根据哈希值来判断是落在哪条链表上
294         return empLinkedListArr[hashValue].add(empNode);
295     }
296 
297     /**
298      * 删除
299      * @param empNo
300      * @return
301      */
302     public boolean delete(int empNo) {
303         int hashValue = hashValue(empNo);
304         //根据哈希值判断是在哪条链表上
305         return empLinkedListArr[hashValue].delete(empNo);
306     }
307 
308     /**
309      * 更新
310      * @param empNode
311      * @return
312      */
313     public boolean update(EmpNode empNode) {
314         int hashValue = hashValue(empNode.getEmpNo());
315         //根据哈希值判断是在哪条链表上
316         return empLinkedListArr[hashValue].update(empNode);
317     }
318 
319     /**
320      * 查找
321      * @param empNo
322      * @return
323      */
324     public EmpNode find(int empNo) {
325         int hashValue = hashValue(empNo);
326         //根据哈希值判断是在哪条链表上
327         return empLinkedListArr[hashValue].find(empNo);
328     }
329 
330     /**
331      * 遍历
332      */
333     public void list() {
334         for (int i = 0; i < empLinkedListArr.length; i++) {
335             System.out.println("arr[" + i + "]: " + empLinkedListArr[i].toString());
336         }
337     }
338 }
复制代码

 

posted @   Java厨师长  阅读(96)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示