哈希冲突和内存溢出

哈希冲突和内存溢出

哈希冲突产生的原因

哈希是通过对数据进行再压缩,提高效率的一种解决方法 ,但是通过哈希函数产生的哈希值是有限的,而数据的总量可能很大,这就导致总会有不同的数据拥有相同的哈希值,从而产生了哈希冲突。

产生哈希冲突的影响因素

填充比(填充比=数据总数/哈希表长)又叫加载因子,哈希函数,处理哈希冲突的算法。

解决哈希冲突的四种方法

1,开放地址法

线性探测再散列法

按顺序决定值时,如果某数据的值已经存在,则在原来值的基础上往后加一个单位,直至不发生哈希冲突。

二次平方再散列法

按顺序决定值时,如果某数据的值已经存在,则在原来值的基础上先加1的平方个单位,若仍然存在则减1的平方个单位。随之是2的平方,3的平方等等。直至不发生哈希冲突。

伪随机探测再散列法

按顺序决定值时,如果某数据已经存在,通过随机函数随机生成一个数,在原来值的基础上加上随机数,直至不发生哈希冲突。

下面给一个实例:

例如,已知哈翔表长度m=11,咱希函数为: H (key) -kry % 1,则H(47)=3,H(26)-4,H(60) =5,假设下一个关键字为69,则H (69)子,与47中突。如果用线性探则再散列处理中突,下一 个哈新地址为H1=(3+1) %11=4,仍然冲突,再找下一个哈希地址为H2= (3+2) %II=5,还是中突,继续找下一个哈系地址为H3- 8+3) %11-6,此时不再冲突,将6填入5号单元,参图826 (国)。如果用二次探则再散列处理冲突,下一个咱新地址为H1=(3+12)%11-4,仍然中突,再找下一个哈新地址为H2= (3-12)5%11-2.时不再冲突,将69填入2号单元,参图8.26 (b).如果用伪随机探别再最列处理冲突,且伪随机救序列为: 2, 5, 9,....则下一个哈新地址为H1-(3+2)%11-5, 仍然中突,周拔下一个哈新地址为H2-(3+5) *511-8,不再冲突,将6填入1号单元。

以下是上述三种处理冲突的方法:

由上述例子可以看出,线性探测再散列容易发生“二次聚类”。但是线性探测再散列的优点:只要哈希表有空余就一定能找到一个不冲突的哈希地址,而二次探测再散列和伪随机数探测再散列不一定。

链式地址法

链式地址法同时也是HashMap解决哈希冲突的方法,平均查找长度ASL=(1*7+2*4+3*1)/12=1.5

对于相同的值,使用链表进行连接。使用数组存储每一个链表。

优点:

(1)拉链法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短;

(2)由于拉链法中各链表上的结点空间是动态申请的,故它更适合于造表前无法确定表长的情况;

(3)开放定址法为减少冲突,要求装填因子α较小,故当结点规模较大时会浪费很多空间。而拉链法中可取α≥1,且结点较大时,拉链法中增加的指针域可忽略不计,因此节省空间;

(4)在用拉链法构造的散列表中,删除结点的操作易于实现。只要简单地删去链表上相应的结点即可。 缺点:

指针占用较大空间时,会造成空间浪费,若空间用于增大散列表规模进而提高开放地址法的效率。

再哈希法、建立公共溢出区法

由于这两种方法不常用,所以这里只做简单的介绍

再哈希法:对于冲突的哈希值再次进行哈希处理,直至没有哈希冲突。这种方法不易产生聚集,但增加计算时间。

建立公共溢出区法:建立公共溢出区存储所有哈希冲突的数据。

内存溢出产生的原因

引起内存溢出的原因有很多种,常见的有以下几种: 1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据; 2.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收; 3.代码中存在死循环或循环产生过多重复的对象实体; 4.使用的第三方软件中的BUG; 5.启动参数内存值设定的过小;

几种解决方法

堆设置jvm值的方法是通过-Xms(堆的最小值),-Xmx(堆的最大值)栈设置栈大小的方法是设置-Xss参数PermGen space第三个异常是关于perm的异常内容,我们需要的是设置方法区的大小,实现方式是通过设置-XX:PermSize和-XX:MaxPermSize参数DirectMemory第四个异常估计遇到的人就不多了,是DirectMemory内存相关的

相关推荐

mobile288-365 Watch Me Work (Audio)

Watch Me Work (Audio)

📅 07-04 👁️ 9440
365体育平台真假怎么分 派派app怎么提现 派派怎么提现到微信钱包
365平台赌博 5个吸引人的标题写法

5个吸引人的标题写法

📅 06-30 👁️ 323