Emp

  1. /**
  2. * 表示一个雇员
  3. */
  4. class Emp{
  5. public int id;
  6. public String name;
  7. public Emp next;//next 默认为空
  8. public Emp(int id, String name) {
  9. this.id = id;
  10. this.name = name;
  11. }
  12. }

HashTab

  1. ///创建hashTab 管理多条链表
  2. class HashTab{
  3. // 数组里面放的是链表
  4. private EmpLinkedList[] empLinkedListArray;
  5. //
  6. private Integer size = 7;
  7. // 构造器
  8. public HashTab(int size) {
  9. // 初始化empLinkedListArray
  10. empLinkedListArray = new EmpLinkedList[size];
  11. // ? 留一个坑
  12. // 这里能直接用么
  13. /*
  14. * add:添加雇员
  15. list:显示雇员
  16. exit:退出雇员
  17. add
  18. 输入id
  19. tom
  20. Exception in thread "main" java.util.InputMismatchException
  21. at java.util.Scanner.throwFor(Scanner.java:864)
  22. at java.util.Scanner.next(Scanner.java:1485)
  23. at java.util.Scanner.nextInt(Scanner.java:2117)
  24. at java.util.Scanner.nextInt(Scanner.java:2076)
  25. at com.atguigu.hashtab.HashTabDemo.main(HashTabDemo.java:30)
  26. Process finished with exit code 1
  27. * */
  28. // 这个时候不要忘了, 分别初始化 每个链表
  29. for (int i = 0; i < size; i++) {
  30. // 数组中的每一个元素都需要创建一把
  31. empLinkedListArray[i] = new EmpLinkedList();
  32. }
  33. }
  34. // 添加雇员
  35. public void add(Emp emp) {
  36. // 根据员工的id,得到该员工应当加入到,哪条链表
  37. int empLinkedListNO = hashFun(emp.id);
  38. // 将emp 添加到对应的链表中
  39. empLinkedListArray[empLinkedListNO].add(emp);
  40. }
  41. // 不管你是什么操作,总是要找链表
  42. // 遍历所有的链表
  43. public void list() {
  44. // 遍历Hash表
  45. for (int i = 0; i < size; i++) {
  46. empLinkedListArray[i].list(i);
  47. }
  48. }
  49. // 编写一个散列函数
  50. // 散列函数有很多种写法
  51. // 这里使用简单的方法-取模法
  52. public int hashFun(int id) {
  53. return id % size;
  54. }
  55. /**
  56. * 更根据输入的id,查找雇员
  57. * @param id
  58. */
  59. public void findEmpById(int id) {
  60. // 使用散列函数确定到哪条链表查找
  61. int empLinkedListNO = hashFun(id);
  62. Emp emp = empLinkedListArray[empLinkedListNO].findEmpById(id);
  63. if (emp != null) {
  64. // 说明找到了
  65. System.out.println("找到了该雇员");
  66. System.out.printf("在第%d条链表中找到了该雇员,id = %d",id,empLinkedListNO+1);
  67. } else {
  68. System.out.println("在哈希表中,没有找到该雇员~");
  69. }
  70. }
  71. }

EmpLinkedList

  1. class EmpLinkedList{
  2. // 头指针, 执行第一个Emp,因此我们这个链表的head,是直接 指向第一个Emp
  3. private Emp head;
  4. //添加雇员到链表
  5. // 说明.
  6. // 1. 假定,当添加雇员的时候,id是自增长的,即id 的分配总是从小到大
  7. public void add(Emp emp) {
  8. // 如果是添加第一个雇员
  9. if (head == null) {
  10. head = emp;
  11. return;
  12. }
  13. // 如果不是添加第一个雇员,则使用一个辅助的指针,帮助定位到最后
  14. Emp currEmp = head;
  15. while (true) {
  16. if (currEmp.next == null) {
  17. // 说明到链表最后
  18. break;
  19. }
  20. // 后移
  21. currEmp = currEmp.next;
  22. }
  23. // 退出时,直接将emp 加入链表
  24. currEmp.next = emp;
  25. }
  26. // 遍历链表的雇员信息
  27. public void list(int no) {
  28. // 判断是否为空
  29. if (head == null) {
  30. // 说明链表为空
  31. System.out.println("当前链"+no+"表为空!");
  32. return;
  33. }
  34. // 没有空
  35. // 打印信息
  36. System.out.println("当前链"+no+"表的信息为");
  37. // 辅助指针
  38. Emp currEmp = head;
  39. while (true) {
  40. System.out.printf("=> id =%d name = %s\t",currEmp.id,currEmp.name);
  41. if (currEmp.next == null) {
  42. // 说明,currEmp 已经是最后节点
  43. break;
  44. }
  45. // 后移 遍历
  46. currEmp = currEmp.next;
  47. }
  48. System.out.println();
  49. }
  50. /**
  51. * // 根据id 查找雇员
  52. * // 如果查找到 ,就返回Emp,如果没有找打到,就返回null
  53. * @param id
  54. * @return
  55. */
  56. public Emp findEmpById(int id) {
  57. // 判断链表是否为空
  58. if (head == null) {
  59. System.out.println("链表为空");
  60. return null;
  61. }
  62. //辅助指针
  63. Emp curEmp = head;
  64. while (true) {
  65. //
  66. if (curEmp.id == id) {
  67. // 找到
  68. break;
  69. // 这个时候,currEmp就指向了要查找的雇员
  70. }
  71. // 退出
  72. if (curEmp.next == null) {
  73. // 说明遍历当前链表没有找到该雇员
  74. curEmp = null;
  75. }
  76. // 后移
  77. curEmp = curEmp.next;
  78. }
  79. return curEmp;
  80. }
  81. }

主函数

  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. int findId = scanner.nextInt();
  29. hashTab.findEmpById(findId);
  30. break;
  31. case "exit":
  32. scanner.close();
  33. System.exit(0);
  34. default:
  35. break;
  36. }
  37. }
  38. }
  1. add:添加雇员
  2. list:显示雇员
  3. find:查找雇员
  4. exit:退出雇员
  5. add
  6. 输入id
  7. 1
  8. 输入名字
  9. tom
  10. add:添加雇员
  11. list:显示雇员
  12. find:查找雇员
  13. exit:退出雇员
  14. add
  15. 输入id
  16. 2
  17. 输入名字
  18. jack
  19. add:添加雇员
  20. list:显示雇员
  21. find:查找雇员
  22. exit:退出雇员
  23. add
  24. 输入id
  25. 3
  26. 输入名字
  27. pin
  28. add:添加雇员
  29. list:显示雇员
  30. find:查找雇员
  31. exit:退出雇员
  32. add
  33. 输入id
  34. 6
  35. 输入名字
  36. nanc
  37. add:添加雇员
  38. list:显示雇员
  39. find:查找雇员
  40. exit:退出雇员
  41. list
  42. 当前链0表为空!
  43. 当前链1表的信息为
  44. => id =1 name = tom
  45. 当前链2表的信息为
  46. => id =2 name = jack
  47. 当前链3表的信息为
  48. => id =3 name = pin
  49. 当前链4表为空!
  50. 当前链5表为空!
  51. 当前链6表的信息为
  52. => id =6 name = nanc
  53. add:添加雇员
  54. list:显示雇员
  55. find:查找雇员
  56. exit:退出雇员
  57. add
  58. 输入id
  59. 123
  60. 输入名字
  61. sme
  62. add:添加雇员
  63. list:显示雇员
  64. find:查找雇员
  65. exit:退出雇员
  66. list
  67. 当前链0表为空!
  68. 当前链1表的信息为
  69. => id =1 name = tom
  70. 当前链2表的信息为
  71. => id =2 name = jack
  72. 当前链3表的信息为
  73. => id =3 name = pin
  74. 当前链4表的信息为
  75. => id =123 name = sme
  76. 当前链5表为空!
  77. 当前链6表的信息为
  78. => id =6 name = nanc
  79. add:添加雇员
  80. list:显示雇员
  81. find:查找雇员
  82. exit:退出雇员
  83. add
  84. 输入id
  85. 678
  86. 输入名字
  87. vicr
  88. add:添加雇员
  89. list:显示雇员
  90. find:查找雇员
  91. exit:退出雇员
  92. list
  93. 当前链0表为空!
  94. 当前链1表的信息为
  95. => id =1 name = tom
  96. 当前链2表的信息为
  97. => id =2 name = jack
  98. 当前链3表的信息为
  99. => id =3 name = pin
  100. 当前链4表的信息为
  101. => id =123 name = sme
  102. 当前链5表为空!
  103. 当前链6表的信息为
  104. => id =6 name = nanc => id =678 name = vicr
  105. add:添加雇员
  106. list:显示雇员
  107. find:查找雇员
  108. exit:退出雇员
  109. add
  110. 输入id
  111. 389
  112. 输入名字
  113. wef
  114. add:添加雇员
  115. list:显示雇员
  116. find:查找雇员
  117. exit:退出雇员
  118. add
  119. 输入id
  120. 9
  121. 输入名字
  122. zho
  123. add:添加雇员
  124. list:显示雇员
  125. find:查找雇员
  126. exit:退出雇员
  127. list
  128. 当前链0表为空!
  129. 当前链1表的信息为
  130. => id =1 name = tom
  131. 当前链2表的信息为
  132. => id =2 name = jack => id =9 name = zho
  133. 当前链3表的信息为
  134. => id =3 name = pin
  135. 当前链4表的信息为
  136. => id =123 name = sme => id =389 name = wef
  137. 当前链5表为空!
  138. 当前链6表的信息为
  139. => id =6 name = nanc => id =678 name = vicr
  140. add:添加雇员
  141. list:显示雇员
  142. find:查找雇员
  143. exit:退出雇员
  144. add
  145. 输入id
  146. 34
  147. 输入名字
  148. mach
  149. add:添加雇员
  150. list:显示雇员
  151. find:查找雇员
  152. exit:退出雇员
  153. list
  154. 当前链0表为空!
  155. 当前链1表的信息为
  156. => id =1 name = tom
  157. 当前链2表的信息为
  158. => id =2 name = jack => id =9 name = zho
  159. 当前链3表的信息为
  160. => id =3 name = pin
  161. 当前链4表的信息为
  162. => id =123 name = sme => id =389 name = wef
  163. 当前链5表为空!
  164. 当前链6表的信息为
  165. => id =6 name = nanc => id =678 name = vicr => id =34 name = mach
  166. add:添加雇员
  167. list:显示雇员
  168. find:查找雇员
  169. exit:退出雇员
  170. find
  171. 输入id
  172. 8
  173. Exception in thread "main" java.lang.NullPointerException
  174. at com.atguigu.hashtab.EmpLinkedList.findEmpById(HashTabDemo.java:237)
  175. at com.atguigu.hashtab.HashTab.findEmpById(HashTabDemo.java:128)
  176. at com.atguigu.hashtab.HashTabDemo.main(HashTabDemo.java:44)
  177. Process finished with exit code 1

最后这里置空要 加上break

  1. if (curEmp.next == null) {
  2. // 说明遍历当前链表没有找到该雇员
  3. curEmp = null;
  4. break;
  5. }

这下就可以了

  1. add:添加雇员
  2. list:显示雇员
  3. find:查找雇员
  4. exit:退出雇员
  5. add
  6. 输入id
  7. 1
  8. 输入名字
  9. tom
  10. add:添加雇员
  11. list:显示雇员
  12. find:查找雇员
  13. exit:退出雇员
  14. add
  15. 输入id
  16. 2
  17. 输入名字
  18. nancy
  19. add:添加雇员
  20. list:显示雇员
  21. find:查找雇员
  22. exit:退出雇员
  23. add4
  24. add:添加雇员
  25. list:显示雇员
  26. find:查找雇员
  27. exit:退出雇员
  28. add
  29. 输入id
  30. 4
  31. 输入名字
  32. victor
  33. add:添加雇员
  34. list:显示雇员
  35. find:查找雇员
  36. exit:退出雇员
  37. list
  38. 当前链0表为空!
  39. 当前链1表的信息为
  40. => id =1 name = tom
  41. 当前链2表的信息为
  42. => id =2 name = nancy
  43. 当前链3表为空!
  44. 当前链4表的信息为
  45. => id =4 name = victor
  46. 当前链5表为空!
  47. 当前链6表为空!
  48. add:添加雇员
  49. list:显示雇员
  50. find:查找雇员
  51. exit:退出雇员
  52. find
  53. 输入id
  54. 6
  55. 链表为空
  56. 在哈希表中,没有找到该雇员~
  57. add:添加雇员
  58. list:显示雇员
  59. find:查找雇员
  60. exit:退出雇员
  61. find
  62. 输入id
  63. 4
  64. 找到了该雇员
  65. 在第4条链表中找到了该雇员,id = 5add:添加雇员
  66. list:显示雇员
  67. find:查找雇员
  68. exit:退出雇员

完整代码

  1. package com.atguigu.hashtab;
  2. import java.util.Scanner;
  3. /**
  4. * ClassName: <br/>
  5. * Description: <br/>
  6. * Date: 2021-02-24 13:10 <br/>
  7. * <br/>
  8. * @project data_algorithm
  9. * @package com.atguigu.hashtab
  10. */
  11. public class HashTabDemo {
  12. public static void main(String[] args) {
  13. // 创建哈希表
  14. HashTab hashTab = new HashTab(7);
  15. // 写一个简单的菜单来测试
  16. String key = "";
  17. Scanner scanner = new Scanner(System.in);
  18. while (true) {
  19. System.out.println("add:添加雇员");
  20. System.out.println("list:显示雇员");
  21. System.out.println("find:查找雇员");
  22. System.out.println("exit:退出雇员");
  23. key = scanner.next();
  24. switch (key) {
  25. case "add":
  26. System.out.println("输入id");
  27. int id = scanner.nextInt();
  28. System.out.println("输入名字");
  29. String name = scanner.next();
  30. // 创建雇员
  31. Emp emp = new Emp(id, name);
  32. hashTab.add(emp);
  33. break;
  34. case "list":
  35. hashTab.list();
  36. break;
  37. case "find":
  38. System.out.println("输入id");
  39. int findId = scanner.nextInt();
  40. hashTab.findEmpById(findId);
  41. break;
  42. case "exit":
  43. scanner.close();
  44. System.exit(0);
  45. default:
  46. break;
  47. }
  48. }
  49. }
  50. }
  51. ///创建hashTab 管理多条链表
  52. class HashTab{
  53. // 数组里面放的是链表
  54. private EmpLinkedList[] empLinkedListArray;
  55. //
  56. private Integer size = 7;
  57. // 构造器
  58. public HashTab(int size) {
  59. // 初始化empLinkedListArray
  60. empLinkedListArray = new EmpLinkedList[size];
  61. // ? 留一个坑
  62. // 这里能直接用么
  63. /*
  64. * add:添加雇员
  65. list:显示雇员
  66. exit:退出雇员
  67. add
  68. 输入id
  69. tom
  70. Exception in thread "main" java.util.InputMismatchException
  71. at java.util.Scanner.throwFor(Scanner.java:864)
  72. at java.util.Scanner.next(Scanner.java:1485)
  73. at java.util.Scanner.nextInt(Scanner.java:2117)
  74. at java.util.Scanner.nextInt(Scanner.java:2076)
  75. at com.atguigu.hashtab.HashTabDemo.main(HashTabDemo.java:30)
  76. Process finished with exit code 1
  77. * */
  78. // 这个时候不要忘了, 分别初始化 每个链表
  79. for (int i = 0; i < size; i++) {
  80. // 数组中的每一个元素都需要创建一把
  81. empLinkedListArray[i] = new EmpLinkedList();
  82. }
  83. }
  84. // 添加雇员
  85. public void add(Emp emp) {
  86. // 根据员工的id,得到该员工应当加入到,哪条链表
  87. int empLinkedListNO = hashFun(emp.id);
  88. // 将emp 添加到对应的链表中
  89. empLinkedListArray[empLinkedListNO].add(emp);
  90. }
  91. // 不管你是什么操作,总是要找链表
  92. // 遍历所有的链表
  93. public void list() {
  94. // 遍历Hash表
  95. for (int i = 0; i < size; i++) {
  96. empLinkedListArray[i].list(i);
  97. }
  98. }
  99. // 编写一个散列函数
  100. // 散列函数有很多种写法
  101. // 这里使用简单的方法-取模法
  102. public int hashFun(int id) {
  103. return id % size;
  104. }
  105. /**
  106. * 更根据输入的id,查找雇员
  107. * @param id
  108. */
  109. public void findEmpById(int id) {
  110. // 使用散列函数确定到哪条链表查找
  111. int empLinkedListNO = hashFun(id);
  112. Emp emp = empLinkedListArray[empLinkedListNO].findEmpById(id);
  113. if (emp != null) {
  114. // 说明找到了
  115. System.out.println("找到了该雇员");
  116. System.out.printf("在第%d条链表中找到了该雇员,id = %d",id,empLinkedListNO+1);
  117. } else {
  118. System.out.println("在哈希表中,没有找到该雇员~");
  119. }
  120. }
  121. }
  122. /**
  123. * 表示一个雇员
  124. */
  125. class Emp{
  126. public int id;
  127. public String name;
  128. public Emp next;//next 默认为空
  129. public Emp(int id, String name) {
  130. this.id = id;
  131. this.name = name;
  132. }
  133. }
  134. class EmpLinkedList{
  135. // 头指针, 执行第一个Emp,因此我们这个链表的head,是直接 指向第一个Emp
  136. private Emp head;
  137. //添加雇员到链表
  138. // 说明.
  139. // 1. 假定,当添加雇员的时候,id是自增长的,即id 的分配总是从小到大
  140. public void add(Emp emp) {
  141. // 如果是添加第一个雇员
  142. if (head == null) {
  143. head = emp;
  144. return;
  145. }
  146. // 如果不是添加第一个雇员,则使用一个辅助的指针,帮助定位到最后
  147. Emp currEmp = head;
  148. while (true) {
  149. if (currEmp.next == null) {
  150. // 说明到链表最后
  151. break;
  152. }
  153. // 后移
  154. currEmp = currEmp.next;
  155. }
  156. // 退出时,直接将emp 加入链表
  157. currEmp.next = emp;
  158. }
  159. // 遍历链表的雇员信息
  160. public void list(int no) {
  161. // 判断是否为空
  162. if (head == null) {
  163. // 说明链表为空
  164. System.out.println("当前链"+no+"表为空!");
  165. return;
  166. }
  167. // 没有空
  168. // 打印信息
  169. System.out.println("当前链"+no+"表的信息为");
  170. // 辅助指针
  171. Emp currEmp = head;
  172. while (true) {
  173. System.out.printf("=> id =%d name = %s\t",currEmp.id,currEmp.name);
  174. if (currEmp.next == null) {
  175. // 说明,currEmp 已经是最后节点
  176. break;
  177. }
  178. // 后移 遍历
  179. currEmp = currEmp.next;
  180. }
  181. System.out.println();
  182. }
  183. /**
  184. * // 根据id 查找雇员
  185. * // 如果查找到 ,就返回Emp,如果没有找打到,就返回null
  186. * @param id
  187. * @return
  188. */
  189. public Emp findEmpById(int id) {
  190. // 判断链表是否为空
  191. if (head == null) {
  192. System.out.println("链表为空");
  193. return null;
  194. }
  195. //辅助指针
  196. Emp curEmp = head;
  197. while (true) {
  198. //
  199. if (curEmp.id == id) {
  200. // 找到
  201. break;
  202. // 这个时候,currEmp就指向了要查找的雇员
  203. }
  204. // 退出
  205. if (curEmp.next == null) {
  206. // 说明遍历当前链表没有找到该雇员
  207. curEmp = null;
  208. break;
  209. }
  210. // 后移
  211. curEmp = curEmp.next;
  212. }
  213. return curEmp;
  214. }
  215. }

扩展

删除功能???