具有许多已定义子集的有序集的数据结构;以相同的顺序检索子集

时间:2011-01-13 15:11:48

标签: sorting data-structures set html-lists

我正在寻找一种有效的方式来存储有序列表/项目集:

  1. 主集中项目的顺序快速变化(子集保持主集的顺序)
  2. 可以定义和检索许多子集
  3. 主集中的成员数量快速增长
  4. 经常在子集中添加和删除成员
  5. 必须允许有效合并任意数量的子集
  6. 理想情况下,性能会偏向于检索任何子集(或合并子集)的前N个项目,并且存储将在内存中(并且最终可能在磁盘上持久存储)

1 个答案:

答案 0 :(得分:2)

我是这个论坛的新成员,我希望你没有忘记这个老问题:)

解决方案

将主集存储在索引数据结构中 - 例如数组(或arraylist,如果您的库支持它)。假设您可以将id与每个集合关联(如果没有,那么您如何知道要检索哪个集合?)。因此,我们现在需要一种方法来找出阵列中哪些元素参与该集合以及哪些元素不参与。

使用矩阵(n x m)n是数组中元素的数量,m是初始数量。 i引用行索引,j引用列索引。

A[i][j] = 0 if ith element is not in jth set
A[i][j] = 1 if ith element is in jth set

不要使用简单的二维数组,请选择ArrayList<ArrayList>。 Java / C#/ C ++支持这样的通用构造,但在其他语言(如Perl)中这样做并不是非常困难。在C#中,您甚至可以使用DataTable

添加新集

的时间

您可以在O(n)时间内添加新内容。只需为该集添加新列,并为该列设置适当的行为1。只要原始数组已排序,就不需要对此集进行排序。

添加新元素的时间

在简单的排序数组中,插入时间为O(log n)。在我们的例子中,我们首先将元素添加到数组中(在我们添加元素的任何索引处,矩阵也将在该索引处获得所有0行)。然后,如果元素属于集合,我们将该列中的条目设置为1。这样,最坏的情况运行时变为O(log n) + O(m)

从集合中获取前N个元素的时间

O(1)时间内选取与该集相对应的列,然后选择N的第一个1条目。这将是线性的。

合并两套

的时间

假设我们将j1和j2的集合合并到j3的第三集。

for (int i = 0; i < n - 1; i++) {
    A[i][j3] = A[i][j1] | A[i][j2];
}

这又是线性的。

删除元素的时间

首先在主数组中找到元素 - 这需要O(log n)次。然后从该数组中删除它,并从矩阵中删除该索引处的行。

数组的有效删除

不要简单地删除,只是将它们标记为已解散。在阈值数量的已解散的列/行后,您可以合并。同样,最初从阵列的高容量开始。现代实现应该自动执行此操作。