zoukankan      html  css  js  c++  java
  • 由一个算法引发的hash讲解

    这个春节真长,闲来无事看看算法视频,不得不说老师讲得透彻深刻、通俗易懂,趁热打铁,做个总结

    请听题:给N(1<N<10)个自然数,每个数的范围为1~10000,现在让你以最快的速度判断某一个数是否在这N个数内,不能用现有的HashMap,该如何实现?

    最直接反应的解决方法

    法一:遍历

    法二:排序+二分

    ......

    不符合本文标题,也不够高级...

    更高级的做法:开辟一个数组,最大下标为N个数中最大的数,将N个数作为数组的下标,数组所有值默认0,若该数存在,则将该数下标对应得值改成1,判断一个K在不在N个树中,直接判断a[k]是否为1即可

    举个栗子:

    给定一组数  2,0,17,31,5,判断10是否在其中。

    1、建立数组a[30]

    2、将a[0]~a[29]的值都默认成0

    3、将a[2]、a[0]、a[17]、a[31]、a[5]改成1

    4、判断a[10]是否等于1,若是则在其中,否则不在

    这就是最基础的hash算法

    但是。。。。

    有个问题:当最大数据过大时,非常浪费空间。如果题目再加个条件,只给10个空间,怎么办???

    取模:10个数,最多就是10个空间。其实就是Hash函数(就是Hash函数,不太懂,

    继续以上述栗子为例

    2%10=2 => a[2] = 2

    0%10=0 => a[0] = 0

    17%10=7 => a[7] = 17

    31%10=1 => a[1] = 31

    5%10=5 => a[5] = 5

    但是。。。。

    又有个问题:当有两个或以上的数取模后值一样怎么办??这就叫hash碰撞,也就是hash冲突

    使用hash算法时,有很多办法解决hash冲突

    法一:使用链表,jdk1.7的HashMap就是用的该算法

    举个栗子:10,2,32,44,77

    a[2]=2,32

    缺点:当所有数取模后的值都一样的时候,就变成了一个单链表,查找很麻烦

    注:Hash的效率取决于冲突的数量,冲突越多,效率就越低,所以一个好的Hash函数可以解决Hash的效率

    法二:使用链表+红黑树,当链表节点大于8时,用红黑树,经过测试后总结。jdk1.8 HashMap用的该算法

  • 相关阅读:
    数据结构与算法(C++)之swap交换
    常用shell脚本
    Java知识库
    jenkins:你们是怎么在控制台实时打印服务启动日志的?
    mqtt压力测试工具emqtt
    postman中获取环境变量和全局变量
    不想当将军的士兵不是好士兵吗?
    永久关闭火狐浏览器自动更新的方法
    性能测试案例:线程池拒绝策略使用不当导致并发一上去就会出现大量报错
    性能测试案例:一个频繁fgc问题
  • 原文地址:https://www.cnblogs.com/lynnetest/p/12269389.html
Copyright © 2011-2022 走看看