• 哈希表


    一----导读:

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

    我们都知道,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 }
  • 相关阅读:
    Swift
    ios高质量博客
    Swift
    UML建模
    Swift
    Swift
    IIS建立.net framework4 应用程序池HTTP 错误 500.21
    zz entity framework vs linq to sql
    zz部署wcf iis
    zzIIS站点中部署WCF项目
  • 原文地址:https://www.cnblogs.com/YXBLOGXYY/p/14661212.html
Copyright © 2020-2023  润新知