Java 哈希表详解(google 公司的上机题)

1 哈希表(散列)-Google 上机题

1) 看一个实际需求,google 公司的一个上机题:
2) 有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,住址..),当输入该员工的 id 时,要求查
找到该员工的 所有信息.
3) 要求: 不使用数据库,尽量节省内存,速度越快越好=>哈希表(散列)

2 哈希表的基本介绍

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通
过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组
叫做散列表。

3. google 公司的一个上机题:

有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,名字,住址..),当输入该员工的 id 时,
要求查找到该员工的 所有信息.
要求:
  1) 不使用数据库,,速度越快越好=>哈希表(散列)
  2) 添加时,保证按照 id 从低到高插入
  3) 使用链表来实现哈希表, 该链表不带表头[即: 链表的第一个结点就存放雇员信息]
  4) 思路分析并画出示意图

  5) 代码实现

public class HashTableDemo {

  public static void main(String[] args) {

    HashTable hashTable = new HashTable(7);

    String key = "";
    Scanner scanner = new Scanner(System.in);
    while(true) {

      System.out.println("add:添加雇员");
      System.out.println("list:查看雇员");
      System.out.println("find:查找雇员");
      System.out.println("del:删除雇员");
      System.out.println("exit:退出");

      key = scanner.next();
      switch (key) {
      case "add":
        System.out.println("请输入id:");
        int id = scanner.nextInt();
        System.out.println("请输入名字:");
        String name = scanner.next();

        Emp emp = new Emp(id, name);
        hashTable.add(emp);
        break;
      case "list":
        hashTable.list();
        break;
      case "find":
        System.out.println("请输入id:");
        int id2 = scanner.nextInt();
        hashTable.findEmpById(id2);
        break;
      case "del":
        System.out.println("请输入id:");
        int id3 = scanner.nextInt();
        hashTable.del(id3);
        break;
      case "exit":
        System.exit(10);
      default:
        break;
      }
    }
  }
}
// emp
class Emp{
  public int id;
  public String name;
  public Emp next;
  public Emp(int id, String name) {
    super();
    this.id = id;
    this.name = name;
  }
}
// EmpLinkedList
class EmpLinkedList{
  // 头指针,执行第一个Emp,因此我们这个链表的head,是直接指向第一个Emp
  private Emp head;

  // id是自增长的
  public void add(Emp emp) {
    // 如果是添加一个雇员
    if(head == null) {
      head = emp;
      return;
    }
    // 如果不是第一个
    Emp curEmp = head;
    while(true) {
      if(curEmp.next == null) {
        break;
      }
      curEmp = curEmp.next;
    }
    curEmp.next = emp;
  }

  public void list(int no) {
    if(head == null) {
      System.out.println("第" + (no+1) + "条链表为空!");
      return;
    }
    System.out.println("第" + (no+1) + "条链表信息为:");
    Emp curEmp = head;
    while(true) {
      System.out.printf("=> id=%d name=%s\t",curEmp.id,curEmp.name);
      if(curEmp.next == null) {
        break;
      }
      curEmp = curEmp.next;
    }
    System.out.println();
  }

  // 根据id查找雇员
  public Emp findEmpByid(int id) {
    if(head == null) {
      System.out.println("链表为空");
      return null;
    }
    Emp curEmp = head;
    while(true) {
      if(curEmp.id == id) {
        break;
      }
      if(curEmp.next == null) {
        System.out.println("遍历完了,没有找到!");
        curEmp = null;
        break;
      }
      curEmp = curEmp.next;
    }
    return curEmp;
  }

  // 根据id进行删除
  public boolean del(int id) {
    boolean flag = false;
    if(head == null) {
      System.out.println("当前链表为空!");
      return flag;
    }
    if(head.id == id) {
      head = null;
      flag = true;
      return flag;
    }
    Emp curEmp = head;
    while(true) {
      // 找到了改雇员
      if(curEmp.next.id == id) {
        curEmp.next = curEmp.next.next;
        curEmp.next = null;
        return (flag == false);
      }
      // 没有找到
      if(curEmp.next == null) {
        System.out.println("没有找改雇员!");
        curEmp = null;
        return flag;
      }
      curEmp = curEmp.next;
    }
  }
}
// 哈希表
class HashTable{

  private EmpLinkedList[] empLinkedListArr;
  private int size;
  public HashTable(int size) {
    super();
    this.size = size;
    empLinkedListArr = new EmpLinkedList[size];

    for(int i = 0; i < size; i++){
      empLinkedListArr[i] = new EmpLinkedList();
    }
  }

  // 添加雇员
  public void add(Emp emp) {
    // 根据员工的id得到改员工应该添加到哪条链表
    int empLinkedListNo = hashFun(emp.id);
    // 将emp添加到对应的链表中
    empLinkedListArr[empLinkedListNo].add(emp);
  }

  public void list() {
    for (int i = 0; i < empLinkedListArr.length; i++) {
      empLinkedListArr[i].list(i);
    }
  }

  public void findEmpById(int id) {
    int empLinkedListNo = hashFun(id);
    Emp emp = empLinkedListArr[empLinkedListNo].findEmpByid(id);
    if(emp != null) {
      System.out.println("在第" + (empLinkedListNo+1) + "条链表中找到id = " + id + "雇员");
    } else {
      System.out.println("在哈希表中没有找到");
    }
  }

  public void del(int id) {
    int empLinkedListNo = hashFun(id);
    boolean flag = empLinkedListArr[empLinkedListNo].del(id);
    if(flag == true) {
      System.out.println("在第" + (empLinkedListNo+1) + "条链表中删除了id = " + id + "雇员");
    } else {
      System.out.println("在哈希表中没有找到");
    }

  }

  public int hashFun(int id) {
    return id %size;
  }
}

注意:不要把链表的第一个节点(头节点)删除了,不然整条链表没了。(还可以改良)

思考:如果 id 不是从低到高插入,但要求各条链表仍是从低到高,怎么解决?

到此这篇关于Java 哈希表(google 公司的上机题)的文章就介绍到这了,更多相关java哈希表内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • java中哈希表及其应用详解

    哈希表也称为散列表,是用来存储群体对象的集合类结构. 什么是哈希表 数组和向量都可以存储对象,但对象的存储位置是随机的,也就是说对象本身与其存储位置之间没有必然的联系.当要查找一个对象时,只能以某种顺序(如顺序查找或二分查找)与各个元素进行比较,当数组或向量中的元素数量很多时,查找的效率会明显的降低. 一种有效的存储方式,是不与其他元素进行比较,一次存取便能得到所需要的记录.这就需要在对象的存储位置和对象的关键属性(设为 k)之间建立一个特定的对应关系(设为 f),使每个对象与一个唯一的存储位置

  • java数据结构和算法中哈希表知识点详解

    树的结构说得差不多了,现在我们来说说一种数据结构叫做哈希表(hash table),哈希表有是干什么用的呢?我们知道树的操作的时间复杂度通常为O(logN),那有没有更快的数据结构?当然有,那就是哈希表: 1.哈希表简介 哈希表(hash table)是一种数据结构,提供很快速的插入和查找操作(有的时候甚至删除操作也是),时间复杂度为O(1),对比时间复杂度就可以知道哈希表比树的效率快得多,并且哈希表的实现也相对容易,然而没有任何一种数据结构是完美的,哈希表也是:哈希表最大的缺陷就是基于数组,因

  • JAVA中哈希表HashMap的深入学习

    深入浅出学Java--HashMap 哈希表(hash table) 也叫散列表,是一种非常重要的数据结构,应用场景及其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,本文会对java集合框架中HashMap的实现原理进行讲解,并对JDK7的HashMap源码进行分析. 一.什么是哈希表 在讨论哈希表之前,我们先大概了解下其他数据结构在新增,查找等基础操作执行性能 数组:采用一段连续的存储单元来存储数据.对于指定下标的查找,时间复杂度为O(1):通过给定值进

  • Java 哈希表详解(google 公司的上机题)

    1 哈希表(散列)-Google 上机题 1) 看一个实际需求,google 公司的一个上机题: 2) 有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,住址..),当输入该员工的 id 时,要求查 找到该员工的 所有信息. 3) 要求: 不使用数据库,尽量节省内存,速度越快越好=>哈希表(散列) 2 哈希表的基本介绍 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通 过把关键码值映射到表中一个位置

  • Java代码实现哈希表(google 公司的上机题)

    目录 1 哈希表(散列)-Google 上机题 2 哈希表的基本介绍 3. google 公司的一个上机题: 1 哈希表(散列)-Google 上机题 1) 看一个实际需求,google 公司的一个上机题: 2) 有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,住址..),当输入该员工的 id 时,要求查 找到该员工的 所有信息. 3) 要求: 不使用数据库,尽量节省内存,速度越快越好=>哈希表(散列) 2 哈希表的基本介绍 散列表(Hash table,也叫哈希表)

  • C语言数据结构哈希表详解

    /* * 程序名:hash.c,此程序演示哈希表的实现,数据元素单链表带头结点. * */ #include <stdio.h> #include <stdlib.h> #include <string.h> // 哈希表中数据元素的结构体. typedef struct Element { unsigned int key; // 关键字. int value; // 数据元素其它数据项,可以是任意数据类型. // char value[1001]; // 数据元素其

  • C++数据结构哈希表详解

    目录 实现 散列函数 开散列方法 闭散列方法(开地址方法) 删除* 实现 哈希表,即散列表,可以快速地存储和查询记录.理想哈希表的存储和查询时间都是 O(1). 本<资料>中哈希表分以下几部分:散列函数.存储和查找时的元素定位.存储.查找.删除操作因为不常用,所以只给出思想,不给出代码. 根据实际情况,可选择不同的散列方法. 以下代码假设哈希表不会溢出. // N表示哈希表长度,是一个素数,M表示额外空间的大小,empty代表"没有元素". const int N=9997

  • Java 中的HashMap详解和使用示例_动力节点Java学院整理

    第1部分 HashMap介绍 HashMap简介 HashMap 是一个散列表,它存储的内容是键值对(key-value)映射. HashMap 继承于AbstractMap,实现了Map.Cloneable.java.io.Serializable接口. HashMap 的实现不是同步的,这意味着它不是线程安全的.它的key.value都可以为null.此外,HashMap中的映射不是有序的. HashMap 的实例有两个参数影响其性能:"初始容量" 和 "加载因子&quo

  • java伪泛型知识点详解

    说明 1.Java中的泛型是伪泛型.这种泛型实现方法称为类型擦除 ,基于这种方法实现的泛型称为伪泛型. 2.由于Java的泛型只在编译阶段发挥作用,因此在写代码时,起到了检查的作用,当代码运行时,它的内部并没有泛型. 实例 List<String> l1 = new ArrayList<String>(); List<Integer> l2 = new ArrayList<Integer>(); System.out.println(l1.getClass(

  • Java并发编程之详解ConcurrentHashMap类

    前言 由于Java程序员常用的HashMap的操作方法不是同步的,所以在多线程环境下会导致存取操作数据不一致的问题,Map接口的另一个实现类Hashtable 虽然是线程安全的,但是在多线程下执行效率很低.为了解决这个问题,在java 1.5版本中引入了线程安全的集合类ConcurrentMap. java.util.concurrent.ConcurrentMap接口是Java集合类框架提供的线程安全的map,这意味着多线程同时访问它,不会影响map中每一条数据的一致性.ConcurrentM

  • Java ConcurrentHashMap用法案例详解

    一.概念 哈希算法(hash algorithm):是一种将任意内容的输入转换成相同长度输出的加密方式,其输出被称为哈希值. 哈希表(hash table):根据设定的哈希函数H(key)和处理冲突方法将一组关键字映象到一个有限的地址区间上,并以关键字在地址区间中的象作为记录在表中的存储位置,这种表称为哈希表或散列,所得存储位置称为哈希地址或散列地址. 二.HashMap与HashTable 1,线程不安全的HashMap 因为多线程环境下,使用HashMap进行put操作会引起死循环,导致CP

  • Java Collection集合用法详解

    目录 1.集合的主要体系及分支 1.1Collection集合及实现类 2.List集合(List是带有索引的,所以多注意索引越界等问题) 2.1 List的实现类 3.Set集合 3.1HashSet(Set的实现类) 3.2TreeSet集合(Set的实现类) 4.集合的高频面试题 4.1Arraylist 与 LinkedList 异同 4.2ArrayList 与 Vector 区别 集合框架底层数据结构总结 1.Collection 1.集合的主要体系及分支 1.1Collection

  • Java Map集合用法详解

    目录 Map集合的概述 常用方法: 遍历方式: Map的实现类: HashMap TreeMap 集合嵌套(补充知识): 高频面试题 1.Map 2.HashMap的底层实现 Map集合的概述 概述:interface Map<K,V> 其中K是键的类型,键是唯一的,不重复.V是值的类型,是可以重复.且每个键可以映射最多一个值.注意的是如果存在两个相同的键时,则会将现在的值替换之前的值. 创建方式:以多态的形式创建对象. 特点: 键值对映射关系 一个键对应一个值 键不能重复,值可以重复 元素存

随机推荐