hash表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构.它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做hash表.
相对于传统的线性查找,需要查找一个数组的元素,需要遍历整个数组,如果存在就返回.
而通过hash表,就能够大幅度的提高查找的效率.
若我们需要查询数组为100的大小,找到一个特定的值,用传统的做法就是依次从数组的0号元素开始,依次遍历到第99号元素,去通过比较元素的大小,最后找到数据是否存在.
而使用hash表,我们的做法就相对来说比较直接和简单,假设数组的元素都为不超过10的正数,,我们可以设置一个0-99大下的table去存放原数组数据出现的次数,table下标就是元数组元素的值,而table值就是元素出现的次数.刚开始时,初始化,table数组全部为0,出现依次加1,就可以很方便的 记录原数组元素出现次数.
对于整数数据则可以直接取余表长,得到特定的存放数据,就可以不用像上一样开那么大的数组,但是若是直接取余表长映射到table会造成冲突的原因
比如说:表长20 当有数据40和60通过hash计算都会映射到0位置,此时我们就需要去解决类似的冲突。解决冲突办法
第一种:
链式解决法:比方说上述的冲突,当20经过映射后已经存放到了table的0号位置,则当60进来时,我们只需要设置一个指针让40指向60链式的去存储,就可以去避免冲突.
第二种方法:
开放地址------线性勘测法:如果遇到冲突就往下一个位置寻找空位.遇到冲突 新位置=原始位置+i(i是冲突的次数)
假设数字关键字有 15 2 38 28 4 12 数组大小为13 下标=关键字%数组大小
则就会变成如下顺序去存储
开放地址------平方勘测法
线性勘测法会让数据可能会让数据扎堆,而平方勘测法就能够去解决这个问题
如果遇到冲突就往下一个位置寻找空位.遇到冲突 新位置=原始位置+i^2(i是冲突的次数)
则遇到冲突步长就会变成平方
数据关键字:15 2 28 19 10 数组大小:13 下标=关键字%数组大小
则就会变成如下顺序去存储
第三种方法:
双哈希法:故名思意,就是在开一个hash函数
R要取比数组尺寸小的质数。比如数组尺寸为13则可
R=7: hash2(关键字)= 7-(关键字%7)
也就是说,二次哈希的结果在1-7之间,不会等于0;如果遇到冲突,
新位置= 原始位置+ i · hash 2(关键字)
数据关键字:15 2 18 28
数组大小: 13
哈希函数: 下标= 关键字 mod 13
哈希函数2: 7-(关键字%7)
如果遇到冲突新位置=原始+ i . hash 2(关键字)
hash表满了怎么办?
满了当然需要对hash表进行扩充,称为再次哈希(Rehashing)
当哈希表数据存储量超过70%,那么就新建一个新的哈希表
新表的尺寸是旧表的2倍以上,选择一个质数
把之前的数据再次
通过哈希计算搬到新表里
旧表: 下标=关键字%7
新表: 下标=关键字%17