表的最佳数据结构

时间:2012-10-24 08:18:44

标签: data-structures sparse-matrix tabular

我们的团队正致力于为移动平台实施表格小部件(其中一个应用程序是移动办公室,如MS Excel)。

我们需要优化用于存储表数据的数据结构(使用简单的二维数组)。

请您建议用于存储表格数据的最佳数据结构。以下是数据结构的一些要求:

  • 表的大小可以达到2 ^ 32 x 2 ^ 32;
  • 大多数表格单元格为空(即表格稀疏),因此最好不要存储空单元格的数据;
  • 数据结构的接口应支持插入/删除行和列;
  • 数据结构应该允许在前向和后向迭代非空单元格;
  • 表的单元格可以合并(即一个单元格可以跨越多行和/或列)。

2 个答案:

答案 0 :(得分:2)

在仔细考虑行/列插入/删除问题之后,我想出了一些看起来很有希望的东西。

首先,创建并维护2个排序数据结构(例如搜索树),其中包含至少有一个非空单元格的所有水平索引和所有垂直索引。

对于此表:

 ABCDE
1
2*
3 %  #
4
5   $

你有:

  1. A,B,D,E - 使用水平指数
  2. 2,3,5 - 使用垂直指数
  3. 将这些A,B,D,E,2,3,5索引值存储在前面提到的2个结构中的某种节点中,以便您可以知道节点在内存中的地址(同样,一棵树)将某些内容链接到它节点非常适合。)

    在每个单元格(非空)中都有一对指向描述其位置的索引节点的链接(我使用&来表示对节点的链接/引用):

    • *:& 2,& A
    • %:& 3,& B
    • #:& 3,& E
    • $:& 5,& D

    这足以定义一个表。

    现在,我们如何处理行/列插入?我们将新的行/列索引插入相应的(水平或垂直)索引数据结构中,并更新其后的索引值(=向右或向下)。然后我们为这个新的行/列添加新的单元格(如果有的话)并将它们链接到适当的索引节点。

    例如,让我们在第3行和第4行之间插入一行,然后在4C(在新行中)添加一个带@的单元格:

     ABCDE
    1
    2*
    3 %  #
    4  @   <- new row 4
    5      <- used to be row 4
    6   $  <- used to be row 5
    

    您的索引结构现在是:

    1. A,B,C(新),D,E - 使用水平指数
    2. 2,3,4(新),6(曾经是5) - 使用垂直指数
    3. 现在,单元格链接到索引节点,如下所示:

      • *:&amp; 2,&amp; A - 与之前相同
      • %:&amp; 3,&amp; B - 与之前相同
      • #:&amp; 3,&amp; E - 与之前相同
      • @:&amp; 4,&amp; C - 链接到新索引节点4和C
      • 的新单元格
      • $:&amp; 6,&amp; D - 曾经是&amp; 5,&amp; D

      但是看看$ cell。它仍然指向与以前相同的两个物理节点,只是垂直/行节点现在包含索引6而不是索引5.

      如果$ cell下面有100个单元节点,比如只占用5个非空行,则需要更新行/垂直索引数据结构中的5个索引,而不是100个。

      您可以以类似的方式删除行和列。

      现在,为了使这一切变得有用,您还需要能够通过其坐标找到每个单元格。

      为此,您可以创建另一个排序数据结构(同样可能是搜索树),其中每个键都是索引节点地址的组合,值是单元格数据的位置(或单元格数据本身)

      有了这个,如果你想进入单元格3B,你会在索引数据结构中找到3和B的节点,取其地址&amp; 3和&amp; B,将它们组合成&amp; 3 * 2 32 +&amp; B并使用它作为键来定位我刚刚定义的第3个数据结构中的%单元格。 (注意:2 32 实际上是2 指针大小的位,并且可能因系统而异。)

      无论其他单元格发生什么,%的单元格链接中的地址&amp; 3和&amp; B将保持不变,即使%单元格的索引从3B变为其他单元格。

      您可以轻松地在此基础上开发迭代。

      合并也应该是可行的,但我没有关注它。

答案 1 :(得分:0)

我建议您像在excel中一样存储键值对。例如,想想你的excel文档有列A - AA等...和行1 - 256000 ......等所以只需存储具有日期的值,就像在某种类型的键值对中一样。

例如:

someKeyValueStore = new KeyValueStore();

someData = new Cell(A1,"SomeValue");

someOtherData = new Cell(C2,"SomeOtherValue");

someKeyValueStore.AddKeyValuePair(someData);
someKeyValueStore.AddKeyValuePair(someOtherData);

在这种情况下,您根本不必关心空单元格。您只能访问非空的。当然,您可能希望跟踪集合中的键,以便您可以轻松查看是否有特定键的值。但这基本上是处理它的最简单方法。