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