• 怎么解决 hash 冲突


    开放定址法:
    线性探测再散列
    二次探测再散列
    伪随机
    再hash:
    同时构造,多个不同的hash函数
    链地址:
    链表,
    建立公共溢出区:
    分为基本表和溢出表两个部分

    开放散列(open hashing)/ 拉链法(针对桶链结构)

    1)优点:
     ①对于记录总数频繁可变的情况,处理的比较好(也就是避免了动态调整的开销)
     ②由于记录存储在结点中,而结点是动态分配,不会造成内存的浪费,所以尤其适合那种记录本身尺寸(size)很大的情况,因为此时指针的开销可以忽略不计了 
    删除记录时,比较方便,直接通过指针操作即可
     
    2)缺点: 
    ①存储的记录是随机分布在内存中的,这样在查询记录时,相比结构紧凑的数据类型(比如数组),哈希表的跳转访问会带来额外的时间开销
     ②如果所有的 key-value 对是可以提前预知,并之后不会发生变化时(即不允许插入和删除),可以人为创建一个不会产生冲突的完美哈希函数(perfect hash function),此时封闭散列的性能将远高于开放散列
     ③由于使用指针,记录不容易进行序列化(serialize)操作

    封闭散列(closed hashing)/ 开放定址法

    1)优点: ①记录更容易进行序列化(serialize)操作 
    如果记录总数可以预知,可以创建完美哈希函数,此时处理数据的效率是非常高的
     
    2)缺点:
     ①存储记录的数目不能超过桶数组的长度,如果超过就需要扩容,而扩容会导致某次操作的时间成本飙升,这在实时或者交互式应用中可能会是一个严重的缺陷
     ②使用探测序列,有可能其计算的时间成本过高,导致哈希表的处理性能降低
     ③由于记录是存放在桶数组中的,而桶数组必然存在空槽,所以当记录本身尺寸(size)很大并且记录总数规模很大时,空槽占用的空间会导致明显的内存浪费 
    删除记录时,比较麻烦。比如需要删除记录a,记录b是在a之后插入桶数组的,但是和记录a有冲突,是通过探测序列再次跳转找到的地址,所以如果直接删除a,a的位置变为空槽,而空槽是查询记录失败的终止条件,这样会导致记录b在a的位置重新插入数据前不可见,所以不能直接删除a,而是设置删除标记。这就需要额外的空间和操作。
  • 相关阅读:
    ArcEngine中删除地物点(C#)
    Siliverlight常识
    ArcEngine 中打开数据源的连接 AO学习资料笔记
    第一次执行时没有问题,重复执行会出错、GP循环
    理解 ArcObjects 中的游标
    AO 中关于坐标系统的感想 AO学习资料 阅读
    http://www.chinabzw.com/bzlist/7_1.htm
    Delphi 文件操作(4)Reset
    c 语言指针
    Delphi 获取星期几
  • 原文地址:https://www.cnblogs.com/zuopy/p/7966601.html
Copyright © 2020-2023  润新知