内存高效结构,以原始顺序跟踪数组的子集

Posted

技术标签:

【中文标题】内存高效结构,以原始顺序跟踪数组的子集【英文标题】:memory efficient structure to track a subset of an array in its original order 【发布时间】:2014-11-01 14:09:02 【问题描述】:

我正在使用 C#,但我不认为这是一个特定于语言的问题。

我正在研究数据结构以跟踪大型数组的子集。例如,我有一个不断变化的字符数组,我想跟踪其中的元音。我想以保持原始顺序的方式跟踪它们。

为了说明,假设当前的字符数组是:[A, B, D, C, I, A, E, F]。我想要的元音子集是 [A, I, A, E]。如果一段时间后字符数组变为 [T, B, D, C, I, A, E, F](第一个元素从 A 变为 T),则元音子集将变为 [I, A, E]。

元音子集将像数组一样被频繁地随机访问:元音[0]、元音[3] ...等。

因此我可以总结一下我的数据结构所需的特性:

1) 内存高效 - 底层数组和子集都可以很大。我正在对一百万个条目进行基准测试。

2) 子集中必须保持底层数组中元素的原始顺序。

3) 快速的随机访问速度。我将像使用数组一样使用子集。

4) 删除和插入需要高效。我在底层数组上有更改通知 - 例如。当底层数组中的第 i 个字符发生变化时,我会收到一条通知,提示“第 i 个元素已从 A 更改为 B”。但是我需要在子集中插入或删除相应的项目

5) 如果要有所作为,我更喜欢更快的删除,我可以放弃插入的性能。我们的应用程序的性质告诉我,对子集的插入要多得多比删除少,通常发生在尾部。但是经常发生的删除总是在子集的头部或中间部分。

PS。我已经看到了一种快速删除数组元素的聪明方法:记录数组中有多少元素。删除元素时,将其与数组中的最后一个元素交换并减少计数器。它使删除成为 O(1) 操作。虽然不缩小数组会浪费一些内存,但我很满意,因为数据结构只是一个数组——它足够紧凑。 这种方法的唯一问题是:它违反了要求 (2)。发生删除时,子集中元素的顺序会从原来的顺序发生变化。

编辑: 在阅读了几个答案后,我意识到我可以用更有趣的方式提出这个问题(至少我认为它更有趣:)):

我绝对同意计数的 B 树将是一个可行的解决方案。但我不需要支持: 1) 元素查找。例如我不需要找到我的子集中的第一个“A”在哪里 2)我不需要任何排序。我只想保持原来的顺序。

看来我根本不需要对元素进行任何比较。我知道大多数排序的数据结构都是基于元素比较的。我知道这就是最佳复杂度为 O(log n) 的原因。我想知道如果我不需要任何比较,是否可以提高三个操作(随机访问、插入、删除)中的任何一个的复杂性,或者降低内存复杂性?

【问题讨论】:

您希望字符数组中有多少百分比是元音? 字符数组只是一个例子。子集/基础比率各不相同。这实际上取决于我们应用程序的用户正在尝试做什么。因此,虽然我知道如果我可以对数据分布做出假设,我可能会获得一些性能优势,但我想找到一个更通用的解决方案 【参考方案1】:

我认为您需要一个order statistic balanced binary tree,因为它维护元素的顺序并且还支持在O(logn) 中的插入和删除。所有操作的查找、插入和删除都是O(logn)

算法:-

1. store required values in tree as <index,vowel> pairs 
2. keep index as key for tree node.
3. You can lookup nth element in tree in O(logn)
4. You can delete element in O(logn)
5. You can insert element in O(logn)
6. Space requirement is O(n) with extra memory for size variables

【讨论】:

谢谢。该链接看起来很有帮助。我们确实已经实现了这样一个计数 B 树。但它仅在需要更花哨的排序时使用。但是我想知道,如果我不需要元素查找和基于比较的排序,是否可以进一步减少内存占用或使基于索引的访问线性化? 您需要在此排序,因为您的数组在每次插入和删除后都会发生变化,并且您想按照数组中的索引顺序对元音进行排序?查找只是 DS 的一个额外好处,但删除查找并不能降低空间复杂度。

以上是关于内存高效结构,以原始顺序跟踪数组的子集的主要内容,如果未能解决你的问题,请参考以下文章

无需替换的内存高效随机数迭代器

具有原始类型的单个数组成员的标准布局结构的保证内存布局

数据结构之顺序表(数组)和链表

(java实现)顺序表-ArrayList

数据结构与算法之数组

数据结构——1数组