我正在使用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)。我想知道如果我不需要进行任何比较,是否有可能提高三种操作(随机访问,插入,删除)中任何一种的复杂性(或随机访问,插入,删除)或降低内存复杂度?
答案 0 :(得分:2)
我认为您需要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