【问题标题】:Simple space efficient implementations of an associative collection in C?C中关联集合的简单空间高效实现?
【发布时间】:2011-07-09 22:51:51
【问题描述】:

我正在寻找一个关联集合,它支持在至少 O(Log(N)) 时间内通过键检索和插入值(删除不重要),并且在代码方面具有非常低的内存开销大小和运行时内存消耗。

我正在为一个用 C 编写的小型嵌入式应用程序执行此操作,因此我试图最大限度地减少所需的代码量和消耗的内存量。

Google sparse hash data structure 如果不是用 C++ 编写的,那么它是可能的,并且更简单。

我知道的大多数哈希表实现都使用大量额外空间,至少需要两倍于键值总数的空间,或者每个条目需要额外的指针(例如桶链哈希算法) .在我的结构中,键值对只是两个指针。

目前我正在使用一个已排序的键/值对数组,但插入是 O(N)。我不禁认为必须有一个聪明的方法来改善插入的摊销运行时间,例如通过分组插入,但我没有任何成功。

我认为这在某些圈子中一定是一个比较知名的问题,所以为了让这个不太主观,我想知道上述问题最常见的解决方案是什么?

[编辑:]

一些可能相关的附加信息:

  • 键是整数
  • 值的数量可能很小,从 1 到 2^32。
  • 使用模式是不可预测的。
  • 我希望尽可能降低内存消耗(例如,将所需内存大小增加一倍,这并不理想)

【问题讨论】:

  • 您的工作量如何?预期的元素数量是多少?你的元素的大小是多少?键总是整数吗?字符串?还是无效*?这是我要问的许多问题中的一部分。
  • 看到你已经回答了我的一些问题,我想问更多:你可以使用动态分配吗?你的动态分配器效率高吗(快速?碎片内存邪恶?开销?)你能负担得起偶尔的繁重计算吗?如果存在值,您会进行大量测试,还是您几乎确定所有请求的键都存在?你能负担得起 O(log²(n)) 吗?你不知道你的工作量也是令人惊讶的。如果您的程序依赖于外部输入,那么您应该使用混合工作负载进行基准测试。如果您的程序不完整,请不要优化。

标签: c data-structures memory-management hashtable associative-array


【解决方案1】:

查看binary search tree 并克服最坏的情况(搜索和插入的复杂度为 O(n))使用balanced tree

【讨论】:

  • 二叉树每个节点有两个指针的开销,平衡需要公平数量的代码。
  • 几乎每个问题都与找到正确的折衷方案有关。想要速度?您为不同的预计算值等消耗内存/代码。想要更少的代码或更少的内存,您会失去性能。
  • 这是一个不错的答案。我正在投票。我希望找到一种在内存方面更有效的解决方案,但这可能是我能做的最好的。
【解决方案2】:

您可以使用不使用链接的哈希表,例如线性探测或布谷鸟哈希方案。后备实现只是一个数组,负载因子在 0.5 左右,开销不会太差,实现复杂度(至少对于线性或二次探测而言)不会太多。

如果您想要一个良好的二叉搜索树实现,它可以很好地保证性能并且编码起来不太难,请考虑研究 splay 树。它们保证摊销 O(lg n) 查找,并且每个节点只需要两个指针。平衡步骤也比大多数平衡 BST 容易得多。

【讨论】:

    【解决方案3】:

    我可能会使用带有双重哈希的哈希表来解决冲突。一般的想法是散列你的原始值,如果发生碰撞,则进行第二次散列,给出一个步长值,你将在遍历数组时使用以找到放置值的位置。这很好地利用了内存,因为它没有指针开销,并且在比线性探测高得多的负载因子下保持合理的效率。

    编辑:如果你想要改变你现在正在做的事情,一种可能性是处理集群中的插入:保留一个排序的数组,以及一个单独的新插入集合。当新插入的集合变得太大时,将这些项目合并到主集合中。

    对于二级收藏,您有几个选择。您可以只使用未排序的数组,并进行线性搜索 - 并且只需限制其大小(例如)log(M),其中 M 是主数组的大小。在这种情况下,整体搜索仍然是 O(log N),不增加内存开销,并且保持大多数插入速度非常快。当您将集合合并在一起时,您(通常)希望对辅助集合进行排序,然后与主集合合并。这使您可以将线性合并摊销到辅助集合中的项目数。

    或者,您可以将树用于辅助收藏。这意味着新插入的项目使用额外的指针存储空间,但(再次)保持较小的大小会限制开销。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-02
      • 1970-01-01
      • 2014-08-05
      • 2011-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多