zoukankan      html  css  js  c++  java
  • 哈希表

    看一个实际需求

    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 的顺序是从小到大, 而且不能重复

       

       

       

  • 相关阅读:
    火狐插件火狐黑客插件将Firefox变成黑客工具的七个插件
    memcache安装环境:WINDOWS 7
    PHP正则表达式
    968. 监控二叉树 力扣(困难) dfs 官方说DP
    375. 猜数字大小 II 力扣(中等) 区间动态规划、记忆化搜索
    629. K个逆序对数组 力扣(困难) 区间动态规划
    剑指 Offer 51. 数组中的逆序对 力扣(困难) 巧用归并排序算法
    488. 祖玛游戏 力扣(困难) dfs
    16. 最接近的三数之和 力扣(中等) 双指针
    319. 灯泡开关 力扣(中等) 数论
  • 原文地址:https://www.cnblogs.com/shuzhiwei/p/11210072.html
Copyright © 2011-2022 走看看