• 哈希表


    看一个实际需求

    google公司的一个上机题:

    有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,住址..),当输入该员工的id,要求查找到该员工的所有信息.

    要求: 不使用数据库,尽量节省内存,速度越快越好=>哈希表(散列)

    哈希表的基本介绍

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

    应用实例

    • google公司的一个上机题:

    有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,住址..),当输入该员工的id,要求查找到该员工的所有信息.

    • 要求:
    1. 不使用数据库,,速度越快越好=>哈希表(散列)
    2. 添加时,保证按照id从低到高插入 [课后思考:如果id不是从低到高插入,但要求各条链表仍是从低到高,怎么解决?]
    3. 使用链表来实现哈希表, 该链表不带表头
          [
      : 链表的第一个结点就存放雇员信息]
    • 思路分析并画出示意图

    代码实现[增删改查(显示所有员工,按id查询)]

    • 代码实现

    package com.atguigu.chapter18.hashtab

     

    import scala.io.StdIn

    import util.control.Breaks._

     

    object HashTabDemo {

    def main(args: Array[String]): Unit = {

    //创建HashTab

    val hashTab = new HashTab(7)

    //写一个简单菜单

    var key = " "

    while (true) {

    println("add: 添加雇员")

    println("list: 显示雇员")

    println("find: 查找雇员")

    println("exit: 退出系统")

     

    key = StdIn.readLine()

    key match {

    case "add" => {

    println("输入id")

    val id = StdIn.readInt()

    println("输入名字")

    val name = StdIn.readLine()

    val emp = new Emp(id, name)

    hashTab.add(emp)

    }

    case "find" => {

    println("输入要查找的雇员的id")

    val id = StdIn.readInt()

    hashTab.findEmpById(id)

    }

    case "list" => {

    hashTab.list()

    }

    }

     

    }

    }

    }

     

    //创建Emp

    class Emp(eId: Int, eName: String) {

    val id = eId

    var name = eName

    var next: Emp = null

    }

     

    //创建EmpLinkedList

    class EmpLinkedList {

    //定义头指针, 这里head 我们直接回指向一个雇员

    var head: Emp = null

     

    //添加雇员方法

    //假定,添加的雇员的id是自增的,即雇员分配的id总是从小到大

    //找到链表的最后加入即可

    def add(emp: Emp): Unit = {

     

    //如果是第一个雇员

    if (head == null) {

    head = emp

    return

    }

    //定义辅助指针

    var cur = head

     

    breakable {

    while (true) {

    if (cur.next == null) {

    break()

    }

    cur = cur.next

    }

    }

    //这时cur 指向了链表的最后

    cur.next = emp

     

    }

     

    //遍历链表的方法

    def list(i: Int): Unit = {

    if (head == null) {

    println(s"${i}条链表为空")

    return

    }

     

    print(s"${i}条链表信息为 ")

    //定义辅助指针

    var cur = head

    breakable {

    while (true) {

    if (cur == null) {

    break()

    }

    //输出雇员信息

    printf(" => id=%d name=%s ", cur.id, cur.name)

    cur = cur.next //

    }

    }

    println()

    }

     

    //如果有,返回emp ,没有返回null

    def findEmpById(id: Int): Emp = {

    //遍历

    if (head == null) {

    println("链表为空,没有数据~~")

    return null

    }

     

    var cur = head

     

    breakable {

    while (true) {

    if (cur == null) {

    break()

    }

    if (cur.id == id) {

    break()

    }

    cur = cur.next

    }

    }

    return cur

    }

    }

     

    //size = 700

    class HashTab(val size: Int) { //size 会称为只读属性

    val empLinkedListArr: Array[EmpLinkedList] = new Array[EmpLinkedList](size)

    //初始化我们的empLinkedListArr 的各个元素

    for (i <- 0 until size) {

    empLinkedListArr(i) = new EmpLinkedList

    }

     

    def add(emp: Emp): Unit = {

    //返回该员工,应该加入到那条链表

    val empLinkedListNo = hashFun(emp.id)

    empLinkedListArr(empLinkedListNo).add(emp)

    }

     

    def list(): Unit = { //遍历整个hash

    for (i <- 0 until size) {

    empLinkedListArr(i).list(i)

    }

    }

     

    //编写一个findEmpById

    def findEmpById(id:Int): Unit = {

    //返回该员工,应该加入到那条链表

    val empLinkedListNo = hashFun(id)

    val emp = this.empLinkedListArr(empLinkedListNo).findEmpById(id)

    if (emp!=null) {

    printf(s"在第 $empLinkedListNo 找到id=%d name=%s ", id, emp.name)

    }else{

    printf("没有找到id %d ", id)

    }

    }

    //散列函数, 可以定制

    def hashFun(id: Int): Int = {

    id % size

    }

    }

     

    • 晚上完成的任务
    1. 能够写出一个hashtab
    2. 解决插入的雇员id 的顺序是从小到大, 而且不能重复

       

       

       

  • 相关阅读:
    走了
    地表最简单安装MySQL及配置的方法,没有之一
    周总结
    Codeforces 1323 div2题解ABC
    Code force-CodeCraft-20 (Div. 2) D. Nash Matrix 详解(DFS构造)
    LeetCode 1293. Shortest Path in a Grid with Obstacles Elimination
    LeetCode 1292. Maximum Side Length of a Square with Sum Less than or Equal to Threshold
    LeetCode 1291. Sequential Digits
    LeetCode 1290. Convert Binary Number in a Linked List to Integer
    LeetCode 91. Decode Ways
  • 原文地址:https://www.cnblogs.com/shuzhiwei/p/11210072.html
Copyright © 2020-2023  润新知