我在C中实现了自己的哈希表函数,但目前它不支持调整大小。我想知道除了创建新的空哈希表并将所有内容移动到那里的蛮力方式之外还存在哪些算法?
答案 0 :(得分:5)
有增量调整大小。
来自维基百科:
增量调整大小
一些哈希表实现, 特别是在实时系统中,不能 付出扩大哈希的代价 表一下子,因为它可能 中断时间关键操作。如果 一个人无法避免动态调整大小, 解决方案是执行调整大小 逐渐:
在调整大小期间,分配新的 哈希表,但保留旧表 不变。 在每个查找或删除操作中,检查两个表。 仅在新表中执行插入操作。 在每次插入时,还将r元素从旧表移动到新表 表。 从旧表中删除所有元素后,取消分配它。
确保旧表格 在新的之前完全复制过来 表本身需要放大,它 有必要增加规模 该表至少为(r + 1)/ r在调整大小期间。
所以这不是将旧表中的所有元素移动到新表中的巧妙方法(如果有的话,我还没有看到它);相反,它通过允许迁移逐渐发生来减轻调整大小的负担。
答案 1 :(得分:2)
维基百科在这个主题上有一些words of wisdom。
此外,它不是一个解决方案,但可能是一个解决方案的一部分 - 如果你在Windows下,你可以使用VirtualAlloc系列函数,它允许你保留地址空间而不实际提交内存页面。也就是说,用外行人的话来说,你会做一些类似“malloc”的事情并告诉它“保留1000MB,但只能使前10个可用”。因此,如果你写过10MB,你会得到通常的崩溃。但是,当时间到了扩展时,你只需说“好吧,在第一批之后再给我10MB”。接下来的10MB将在前10MB后直接在地址提供。这就像调整数组大小一样。使用中的实际RAM只能满足您的需求,但事先会保留内存地址,以便其他内存分配操作不会使用它们。
答案 2 :(得分:1)
通常的警告是将其留给客户端代码来预测最佳数量的存储桶。这是可用的,客户端通常会对表中最终会有多少元素进行合理的猜测。如果您想自动执行此操作,则首先必须为存储桶大小声明一个素数数组。当您看到存储桶的负载系数过高时,选择阵列中的下一个素数,重新创建存储桶列表并将元素从旧存储桶移动到新表。