4

通常“可展开”网格表示为列表列表(行列表,每行有单元格列表),这些列表是某种链接列表。在这个数据结构中操作(移除,插入)行非常简单且便宜,它只是重新链接前一个节点的问题,但是当涉及到列时,例如删除一列,它变成了一个很长的操作,我需要'循环'所有行来删除索引单元格。显然这不是好行为,至少对我来说是这样。网格数据结构

我不是在这里说数据库;我发现的一个很好的例子是将一些文本文件转换为文本编辑器(据我所知)文本编辑器主要将行分割成行,并且很容易删除行。我想要删除一列与删除某一行一样廉价和高效。

最后,我需要的是一些多维网格,但我认为任何2D网格都适用于MD,对吗?

+0

所以你想O(1)删除行和列? – 2010-08-23 23:13:15

+0

是的,这就是我所问的。 – KA1 2010-08-24 02:10:55

+0

谢谢大家,我在下面的答案中找到了非常有用的想法。 ,并不能真正推荐其中之一。所有这些都是很好的答案,需要阅读这些问题。 – KA1 2010-08-26 20:06:54

回答

1

你可以有一个二维“链接矩阵”(我忘了正确的术语):

... Col 3 ... Col 4 ... 
     |   | 
... --X-- ... --Y-- ... 
     |   | 
... ... ... ... ... 

每个单元有四个邻居,如图所示。此外,您需要可能指示行/列位置的行和列标题,以及指向每行或列中的第一个单元格。这些最容易表示为没有上邻居的特殊单元格(对于列标题)。

在3到4之间插入新列意味着在列3中迭代单元格X并插入新的右侧邻居Z.此新单元格Z向左连接X并向右连接到Y.您还需要添加新列标题,并垂直链接新单元格。然后可以重新编号4后的所有列的位置(第4列变为第5列)。

... Col 3 Col 4 Col 5 ... 
     |  |  | 
... --X-----Z-----Y-- ... 
     |  |  | 
... ... ... ... ... 

插入柱的费用是用于更新所述列标题O(Ñ)用于插入并连接的新的细胞,并再次O()。这是一个类似的删除过程。

因为每个单元只有四个链接,所以相同的算法用于行插入/删除。

+0

感谢您的回复,但似乎您并不了解我的问题,您的答案是您已将行操作作为列很贵!这与我所需要的相反。简而言之,列删除仍然非常缓慢,因为我仍然必须遍历所有这些单元并重新链接。它并不像删除一行那样简单便宜。 在插入列时,该列将作为列生成'已经'(考虑替换列)。然而,为了简单起见,我使用了'删除'。 – KA1 2010-08-23 03:47:48

+0

删除我的方案中的列与删除行具有相同的算法成本。如果您的行数多于列数,那么绝对成本可能会有所不同 - 但这种成本在每个单元中仍然是线性的。我认为除了推迟某些工作(例如,将某一列标记为已删除,然后在保存时批量删除所有标记的列)之外,您可以做得比这更好。 – Edmund 2010-08-23 04:17:36

+0

我*不*谈论导航,我需要更好的结构*操纵*不用于导航。实际上'列表清单'结构对于导航来说比每个单元格增加更多指针要好得多 再次,我正在寻找更好的解决方案,以便进行有效的数据操作。谢谢。 – KA1 2010-08-23 23:48:25

1

保持原有的数据结构。另外,在创建每个列时给它一个唯一的ID。删除列时,只需将其ID添加到所有删除列标识的哈希表中即可。每当你走一行时,检查每个元素的列id(需要与元素的所有其他数据一起存储),如果它已被删除,则将它与行相拼接。

如果您有每个网格元素可指向的每列数据结构,则不需要散列表和ID。那么你只需要在该数据结构中删除一个位。

顺便说一句,埃德蒙的方案也适合你。即使需要花费O(n)时间来删除长度为n的行或列,您可以推测分摊该成本与创建这n个元素的成本,使得删除O(1)摊销时间成为可能。

0

我知道“链接列表”通常是从理论的角度来理解,但实际上它们通常是低效的。

我会建议朝随机存取容器移动以获得一些速度。最简单的是一个数组,但是根据我们正在谈论的数据大小,双端队列或索引跳过列表/ B *树可能会更好。 (1)(array,deque)/ O(log N)(跳过列表/ B *树)中的给定索引的能力在概念上,它不会变化很多)操作,而不是使用简单链接列表的O(N)。

然后是魔法的时候了。基斯已经暴露了基本思想:而不是实际删除该列,只需将其标记为已删除,然后在您走向结构时将其标记为“跳过”即可。然而,哈希表需要线性步行才能到达第N列。使用Fenwick树会产生计算真实指数的有效方法,然后您可以直接跳到那里。

请注意,将行标记为已删除的关键好处在于操作的明显可能性为undo

另请注意,您可能想要构建一个压缩函数,以消除不时删除的列,而不是让它们累积。