处理具有变化索引的数组的数据结构

时间:2014-01-04 02:12:42

标签: c++ arrays algorithm data-structures

我有一个数组,其中包含8个元素的空间。我想用以下数组指示的索引用数字8,7,...,1填充这个数组:

7 4 4 2 1 2 0 0

你必须注意到某些指数正在重复。这是因为这些数字表示剩余数组的索引

我将引导您完成数组填充的步骤,以便您了解:

初始数组索引

_ _ _ _ _ _ _ _
0 1 2 3 4 5 6 7

第1步

_ _ _ _ _ _ _ 8
0 1 2 3 4 5 6 -

第2步

_ _ _ _ 7 _ _ 8
0 1 2 3 - 4 5 -

注意当我填写“7”时索引如何更新,这样我也可以在索引4处填写“6”,因为索引4是新位置。

第3步

_ _ _ _ 7 6 _ 8
0 1 2 3 - - 4 -

第4步

_ _ 5 _ 7 6 _ 8
0 1 - 2 - - 3 -

第5步

_ 4 5 _ 7 6 _ 8
0 - - 1 - - 2 -

第6步

_ 4 5 _ 7 6 3 8
0 - - 1 - - - -

第7步

2 4 5 _ 7 6 3 8
- - - 0 - - - -

和“1”可以在最后一个地方填写。

如果我必须填写索引i,我已经解决了直接扫描数组中第i个空位的问题。它是O(n ^ 2)。我需要更好。

问题:是否有可以优化上述算法的数据结构?或者算法本身可以改进吗?

注意:我尝试过使用BIT,但失败了。

2 个答案:

答案 0 :(得分:2)

将所有初始索引存储在二叉搜索树中。还与每个节点一起存储总孩子数(所有更深层次)。

只要在数组中插入一个元素,就从O(log n)中的树中删除其索引。同时更新孩子的数量。

对于“新索引”中索引i的数组中的下一个插入,您需要在搜索树的排序中找到i元素,它将为您提供“原始”中的位置指数。由于可以查询每个节点的子节点数,因此也可以在O(log n)中完成。

因此,完整的平均和最差情况复杂度为O(n log n)。

答案 1 :(得分:1)

如果您接受使用额外的O(n)内存,您可以这样做:

  • 创建一个辅助数组,在索引i处存储原始数据数组中第i个空闲位置的索引。因此,如果您的原始数组的索引为0 - 7且索引为1,3,5的位置是空闲的,那么您的辅助数组将如下所示:[1,3,5,-1,-1,-1,-1, - 1],其中-1表示原始数组中没有这样的可用空间量。

  • 为了在数据数组中的第i个自由位置插入一个元素,你可以这样做:

    int j = helperArray[i];
    if (j > -1){
        dataArray[j] = itemYouWantToInsert;
        while (i < helperArray.size() - 1){
              helperArray[i] = helperArray[i+1];
              i++;
          }
          helperArray[i] = -1;
    }
    else
        cout<<"There are less free places in the dataArray.";

插入时间为O(k),其中k =(n-i)。因此,插入的极限时间是O(n),但乐观的是O(1)。 isFree()只是一个示例方法,因为我不知道如何识别dataArray中的“空白空间”。