zcq

    1. package com.atguigu.hashtab;
    2. import java.util.Scanner;
    3. public class HashTabDemo {
    4. public static void main(String[] args) {
    5. //创建哈希表
    6. HashTab hashTab = new HashTab(7);
    7. //写一个简单的菜单
    8. String key = "";
    9. Scanner scanner = new Scanner(System.in);
    10. while(true) {
    11. System.out.println("add: 添加雇员");
    12. System.out.println("list: 显示雇员");
    13. System.out.println("find: 查找雇员");
    14. System.out.println("exit: 退出系统");
    15. key = scanner.next();
    16. switch (key) {
    17. case "add":
    18. System.out.println("输入id");
    19. int id = scanner.nextInt();
    20. System.out.println("输入名字");
    21. String name = scanner.next();
    22. //创建 雇员
    23. Emp emp = new Emp(id, name);
    24. hashTab.add(emp);
    25. break;
    26. case "list":
    27. hashTab.list();
    28. break;
    29. case "find":
    30. System.out.println("请输入要查找的id");
    31. id = scanner.nextInt();
    32. hashTab.findEmpById(id);
    33. break;
    34. case "exit":
    35. scanner.close();
    36. System.exit(0);
    37. default:
    38. break;
    39. }
    40. }
    41. }
    42. }
    43. //创建HashTab 管理多条链表
    44. class HashTab {
    45. private EmpLinkedList[] empLinkedListArray;
    46. private int size; //表示有多少条链表
    47. //构造器
    48. public HashTab(int size) {
    49. this.size = size;
    50. //初始化empLinkedListArray
    51. empLinkedListArray = new EmpLinkedList[size];
    52. //?留一个坑, 这时不要分别初始化每个链表
    53. for(int i = 0; i < size; i++) {
    54. empLinkedListArray[i] = new EmpLinkedList();
    55. }
    56. }
    57. //添加雇员
    58. public void add(Emp emp) {
    59. //根据员工的id ,得到该员工应当添加到哪条链表
    60. int empLinkedListNO = hashFun(emp.id);
    61. //将emp 添加到对应的链表中
    62. empLinkedListArray[empLinkedListNO].add(emp);
    63. }
    64. //遍历所有的链表,遍历hashtab
    65. public void list() {
    66. for(int i = 0; i < size; i++) {
    67. empLinkedListArray[i].list(i);
    68. }
    69. }
    70. //根据输入的id,查找雇员
    71. public void findEmpById(int id) {
    72. //使用散列函数确定到哪条链表查找
    73. int empLinkedListNO = hashFun(id);
    74. Emp emp = empLinkedListArray[empLinkedListNO].findEmpById(id);
    75. if(emp != null) {//找到
    76. System.out.printf("在第%d条链表中找到 雇员 id = %d\n", (empLinkedListNO + 1), id);
    77. }else{
    78. System.out.println("在哈希表中,没有找到该雇员~");
    79. }
    80. }
    81. //编写散列函数, 使用一个简单取模法
    82. public int hashFun(int id) {
    83. return id % size;
    84. }
    85. }
    86. //表示一个雇员
    87. class Emp {
    88. public int id;
    89. public String name;
    90. public Emp next; //next 默认为 null
    91. public Emp(int id, String name) {
    92. super();
    93. this.id = id;
    94. this.name = name;
    95. }
    96. }
    97. //创建EmpLinkedList ,表示链表
    98. class EmpLinkedList {
    99. //头指针,执行第一个Emp,因此我们这个链表的head 是直接指向第一个Emp
    100. private Emp head; //默认null
    101. //添加雇员到链表
    102. //说明
    103. //1. 假定,当添加雇员时,id 是自增长,即id的分配总是从小到大
    104. // 因此我们将该雇员直接加入到本链表的最后即可
    105. public void add(Emp emp) {
    106. //如果是添加第一个雇员
    107. if(head == null) {
    108. head = emp;
    109. return;
    110. }
    111. //如果不是第一个雇员,则使用一个辅助的指针,帮助定位到最后
    112. Emp curEmp = head;
    113. while(true) {
    114. if(curEmp.next == null) {//说明到链表最后
    115. break;
    116. }
    117. curEmp = curEmp.next; //后移
    118. }
    119. //退出时直接将emp 加入链表
    120. curEmp.next = emp;
    121. }
    122. //遍历链表的雇员信息
    123. public void list(int no) {
    124. if(head == null) { //说明链表为空
    125. System.out.println("第 "+(no+1)+" 链表为空");
    126. return;
    127. }
    128. System.out.print("第 "+(no+1)+" 链表的信息为");
    129. Emp curEmp = head; //辅助指针
    130. while(true) {
    131. System.out.printf(" => id=%d name=%s\t", curEmp.id, curEmp.name);
    132. if(curEmp.next == null) {//说明curEmp已经是最后结点
    133. break;
    134. }
    135. curEmp = curEmp.next; //后移,遍历
    136. }
    137. System.out.println();
    138. }
    139. //根据id查找雇员
    140. //如果查找到,就返回Emp, 如果没有找到,就返回null
    141. public Emp findEmpById(int id) {
    142. //判断链表是否为空
    143. if(head == null) {
    144. System.out.println("链表为空");
    145. return null;
    146. }
    147. //辅助指针
    148. Emp curEmp = head;
    149. while(true) {
    150. if(curEmp.id == id) {//找到
    151. break;//这时curEmp就指向要查找的雇员
    152. }
    153. //退出
    154. if(curEmp.next == null) {//说明遍历当前链表没有找到该雇员
    155. curEmp = null;
    156. break;
    157. }
    158. curEmp = curEmp.next;//以后
    159. }
    160. return curEmp;
    161. }
    162. }