【问题标题】:Run time to insert n elements into an empty hash table将 n 个元素插入空哈希表的运行时间
【发布时间】:2010-10-24 00:18:37
【问题描述】:

人们说需要摊销 O(1) 才能放入哈希表。因此,放置 n 个元素必须是 O(n)。然而,对于大 n 而言,情况并非如此,因为正如一位回答者所说,“满足预期摊销 O(1) 所需的只是扩展表并在发生冲突时使用新的随机散列函数重新散列所有内容。”

那么:将 n 个元素插入哈希表的平均运行时间是多少?我意识到这可能是依赖于实现的,所以请提及您正在谈论的实现类型。

例如,如果有 (log n) 个等距碰撞,并且每次碰撞都需要 O(k) 来解决,其中 k 是哈希表的当前大小,那么您将具有以下递归关系:

T(n) = T(n/2) + n/2 + n/2

(也就是说,你花时间插入 n/2 个元素,然后你有一个冲突,需要 n/2 来解决,然后你在没有冲突的情况下执行剩余的 n/2 个插入)。这仍然是 O(n),所以是的。但这合理吗?

【问题讨论】:

    标签: algorithm hash runtime hashtable hashmap


    【解决方案1】:

    这完全取决于您的重新散列效率有多低。具体来说,如果您可以正确估计第二次哈希表的预期大小,您的运行时间仍接近 O(n)。实际上,在确定预期顺序之前,您必须指定 rehash 大小计算的低效程度。

    【讨论】:

    • 请注意,在许多实现中,您可以指定完整哈希图​​的预期大小。因此,如果在开始填充地图之前知道 n,则预期的运行时间仍然是 O(1)。
    • @gnud,这正是我的观点;仅当原始大小错误(或后续大小错误并需要重新哈希等)时才需要重新散列。
    • 是的,我知道——你第二次写了关于估计大小的文章。我想我应该提一下,通常可以在第一次指定大小 =)
    【解决方案2】:

    人们说放入哈希表需要摊销 O(1)。

    从理论上讲,预期摊销 O(1)。

    哈希表本质上是一种随机数据结构,就像快速排序是一种随机算法一样。您需要生成具有一定随机性的哈希函数,否则存在不是 O(1) 的病态输入。

    您可以使用dynamic perfect hashing 实现预期摊销 O(1):

    我最初发布的幼稚想法是在每次碰撞时使用新的随机散列函数重新散列。 (另见perfect hash functions)问题在于,这需要 O(n^2) 空间,来自生日悖论。

    解决方案是有两个哈希表,第二个表用于冲突;通过重建它来解决第二个表上的冲突。该表将包含 O(\sqrt{n}) 个元素,因此会增长到 O(n) 个大小。

    实际上,您通常只使用固定的哈希函数,因为您可以假设(或不在乎)您的输入是病态的,就像您经常快速排序而不预先随机化输入一样。

    【讨论】:

    • 所以这正是我的问题。你说“你需要满足预期的摊销 O(1) 就是扩展表并在发生冲突时使用新的随机散列函数重新散列所有内容。”假设您这样做。如果你没有与 n 次插入发生冲突,那么你肯定有 O(n)。但是,每个 n 个元素的预期碰撞次数是多少,每个元素需要多长时间才能解决?然后我们可以得到一个更准确的 n 次插入哈希表的数字。像 O(n + #col * coltime) - 也许是 O(n + (log n)^2)?
    • 已修复。我忘记了诀窍是有第二张桌子。由于生日悖论,简单地在每次碰撞时重新散列将需要 O(n^2) 空间。
    【解决方案3】:

    所有 O(1) 的意思是操作是在恒定时间内执行的,它取决于数据结构中元素的数量。

    简而言之,这意味着无论您的数据结构有多大,您都必须支付相同的成本。

    实际上,这意味着当您不必存储大量数据时,诸如树之类的简单数据结构通常更有效。根据我的经验,我发现树的速度更快,最多可达 1k 个元素(32 位整数),然后哈希表接管。但像往常一样 YMMW。

    【讨论】:

      【解决方案4】:

      为什么不在您的系统上运行一些测试?也许如果您发布源代码,我们可以返回并在我们的系统上对其进行测试,我们真的可以将其转化为非常有用的讨论。

      决定算法实际花费多少时间的不是实现,而是环境。但是,您可以查看是否有任何基准测试样本可用。我发布结果的问题将毫无用处,因为人们不知道我的系统上还运行着什么,现在有多少 RAM 可用等等。你只能有一个广泛的想法。这和大 O 给你的一样好。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-24
        • 1970-01-01
        相关资源
        最近更新 更多