哈希表

 

一----导读:

  首先要明确一个概念:哈希表不是 算法,而是一种数据结构 。

我们都知道,java代码可以操作数据库,并且从从数据库再返回数据。但是如果频繁的对数据库进行操作,效率较低且存在安全隐患,这时就诞生出了缓存产品,也就是现在常用的redis或者Memcache ,但是以前的 老程序员们没有这些产品怎么办?这时哈希表就出场了。一级缓存不够的话加二级缓存。

 

 哈希表常用的结构:

1)数组+链表

 

 

2)数组+二叉树

 

 

 

二---代码实现哈希表

看一个实际的面试题:

有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id,姓名),

当输入该员工的id时,要求查找到该员工的所有信息。

要求,不使用数据库,速度越快越好

思路分析 :

 

 测试代码:

  1 public class HashTable {
  2     public static void main(String[] args) {
  3         // 创建一个hashtab
  4         HashTab hashTab = new HashTab(7);
  5 
  6         // 写一个简单菜单
  7         String key = "";
  8         Scanner scanner = new Scanner(System.in);
  9         while (true) {
 10             System.out.println("1)添加雇员");
 11             System.out.println("2)显示雇员");
 12             System.out.println("3)退出系统");
 13             key =  scanner.next();
 14             switch (key) {
 15                 case "1":
 16                     System.out.println("输入id");
 17                     int id = scanner.nextInt();
 18                     System.out.println("输入名字");
 19                     String name = scanner.next();
 20                     // 创建雇员
 21                     Emp emp = new Emp(id,name);
 22                     hashTab.add(emp);
 23                     break;
 24                 case "2":
 25                     hashTab.list();
 26                     break;
 27                 case "3":
 28                     scanner.close();
 29                     System.exit(0);
 30 
 31                 default:
 32                     break;
 33 
 34             }
 35         }
 36 
 37 
 38 
 39 
 40     }
 41 }
 42 
 43 // 创建HashTab 管理多条链表
 44 class HashTab {
 45     private EmpLinkedList[] empLinkedListArray;   // 数组里面放的是链表
 46     private int size; // 表示共有多少条链表
 47    //构造器
 48     public HashTab(int size) {  // size表示指定有多少条链表
 49         this.size = size;
 50         // 初始化empLinkedListArray
 51         empLinkedListArray = new EmpLinkedList[size]; // 开辟空间
 52         // 留一个坑 此时的链表数组能不能用?
 53         // 这时不要忘了分别初始化每个链表
 54         for (int i = 0; i < size ;  i++) {
 55              empLinkedListArray[i] = new EmpLinkedList();
 56         }
 57     }
 58 
 59     // 添加雇员
 60     public void add(Emp emp) { // 添加的时候给出一个雇员
 61         // 根据员工的id,得到该员工应当添加到哪条链表
 62         int empLinkedListNo = hashFun(emp.id);
 63         // 将emp添加到对应链表
 64         empLinkedListArray[empLinkedListNo].add(emp);
 65     }
 66 
 67     // 遍历所有的链表(哈希表)
 68     public void list() {
 69         for (int i = 0; i < size ;  i++) {
 70             empLinkedListArray[i].list(i);
 71         }
 72 
 73     }
 74 
 75     // 编写一个散列函数,使用简单的取模法
 76     public int hashFun(int id) {
 77         return id % size;
 78     }
 79 
 80 }
 81 
 82 // 表示雇员
 83 class Emp {
 84     public int id;
 85     public String name;
 86     public Emp next; // next 默认为空指向下一个雇员信息的指针
 87 
 88     public Emp(int id, String name) {  // 带参构造
 89         super();
 90         this.id = id;
 91         this.name = name;
 92     }
 93 }
 94 
 95 // 创建EmpLinkedList ,表示链表
 96 class EmpLinkedList {
 97     // 头指针,执行第一个Emp,因此我们这个链表的head是有效的,直接指向第一个Emp
 98     private Emp head; // 默认null
 99 
100     // 添加雇员到链表
101     // 说明
102     // 1)假定当添加雇员时,id自增长,即id的分配总是从小到大
103     // 因此我们将该雇员直接加入到本链表的最后即可
104     public void add(Emp emp) {
105         // 如果是添加第一个雇员
106         if (head == null) {
107             head = emp;
108             return;
109         }
110         // 如果不是添加第一个雇员,则使用一个辅助指针帮助定位到最后
111         Emp curEmp = head;
112         while(true) {
113             if (curEmp.next == null) { // 说明到链表最后
114                 break;
115             }
116             curEmp = curEmp.next; // 后移
117         }
118         // 退出时直接将emp加入链表
119         curEmp.next = emp;
120     }
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 
140 }

 

posted on 2021-04-22 22:08  Love&Share  阅读(70)  评论(0编辑  收藏  举报

导航