繁体   English   中英

C中关联集合的简单空间高效实现?

[英]Simple space efficient implementations of an associative collection in C?

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

我这样做是为了用C编写的小型嵌入式应用程序,所以我试图最小化所需的代码量和消耗的内存量。

如果它不是用C ++编写的,那么Google稀疏哈希数据结构就有可能,而且更简单。

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

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

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

[编辑:]

一些可能相关的其他信息:

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

查看二叉搜索树并克服最坏情况(搜索和插入都具有O(n)复杂度)使用平衡树

您可以使用不使用链接的哈希表,例如线性探测或布谷鸟哈希方案。 支持实现只是一个数组,负载因子大约为0.5,开销不会太差,实现复杂性(至少对于线性或二次探测)并不算太多。

如果你想要一个良好的二进制搜索树实现,它具有出色的性能保证,并且不易编码,请考虑查看splay树。 它们保证了摊销的 O(lg n)查找,并且每个节点只需要两个指针。 平衡步骤也比大多数平衡BST更容易。

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM