Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 是否有任何方法可以基于插入/删除序列高效地重建集合?_Performance_Algorithm_Data Structures_Collections_Language Agnostic - Fatal编程技术网

Performance 是否有任何方法可以基于插入/删除序列高效地重建集合?

Performance 是否有任何方法可以基于插入/删除序列高效地重建集合?,performance,algorithm,data-structures,collections,language-agnostic,Performance,Algorithm,Data Structures,Collections,Language Agnostic,注意:下面的代码恰好是C#,但任何语言的答案都会对我有所帮助 假设我有一系列操作,而不是一个实际的集合(例如,一个列表),每个操作看起来如下所示: struct ListOperation<T> { public enum OperationType { Insert, Remove } public OperationType Type; public T Element; // irrelevant for OperationType.Remove

注意:下面的代码恰好是C#,但任何语言的答案都会对我有所帮助

假设我有一系列操作,而不是一个实际的集合(例如,一个
列表
),每个操作看起来如下所示:

struct ListOperation<T>
{
    public enum OperationType { Insert, Remove }

    public OperationType Type;
    public T Element; // irrelevant for OperationType.Remove
    public int Index;
}
结构列表操作
{
公共枚举操作类型{Insert,Remove}
公共运营类型;
公共T元素;//与OperationType无关。删除
公共整数指数;
}
是否有某种方法可以基于一系列这样的操作高效地“重建”集合

特别是,我希望避免明显的(低效的)实现,基本上只是创建一个
列表
并调用
Insert
RemoveAt
——对每个元素都执行O(N)操作



更新:假设操作的“序列”实际上是一个具体的集合,其计数是已知的,可以通过索引随机访问(例如,像
列表操作[]
)。我们还可以说,结果集合的实际计数已经知道了(但实际上,在O(N)中,通过计算插入和移除的数量,这将是微不足道的)。还有其他想法吗?

我认为你可以通过使用索引平衡二叉树(一种二叉树,其中每个节点在其左侧和右侧存储节点数)在O(n lg n)中实现这一点。使用此结构,您可以通过遍历树来找到新元素所属的位置,然后执行任何必要的修复来保持平衡条件(例如,如果它是红黑树,则执行红黑树修复),从而在任意点进行最坏情况下的O(lg n)插入或删除

在这种设置下,您可以将所有操作重放到一个树结构中,如O(n lg n)中所示,因为每个操作最多需要O(lg n)才能完成。一旦有了树,就可以按顺序遍历元素,以使它们按正确的顺序返回,并且可以在O(n)时间内将所有值附加到一个生成的列表中,即一个O(n lg n)的网络


我会更仔细地考虑这个问题,看看我能不能想出一种在线性时间内实现这一点的方法。同时,这至少表明,在次二次时间内这样做是可能的。

我有一种预感,可能有一个O(n)算法

步骤1: 基数对索引进行数字排序。需要O(n)个时间。如果从LSB端执行,这是一种稳定的排序

步骤2: 假设有索引为i的操作,但没有索引较小的操作尚未完成。然后我们可以按照正确的顺序重播索引i上的操作。具体来说,“插入”和“删除”操作在做什么我并不清楚。最坏的情况是O(n lg n)和二叉树的思想,但可能可以在O(n)中进行重放,因为它是局部的

步骤3:
将步骤2提到归纳论点,作为正确性的证明。在索引i处的步骤之后,需要维护一个不变量和一个较短的操作列表,因此通过归纳。。。(详细信息).

是否可以从端到端阅读,或者只从前端到端阅读?顺便说一句,插入或删除可能是O(1)。最糟糕的情况是O(n),但我想你知道这是一个可怕的问题。我今天的票数没有了,但明天一到我一定会投更多的票。主要的困难在于
索引
与创建操作(插入/删除)时列表的当前状态相关。@Rune FS:操作本身在任何方向都是可读的。是的,我知道插入/删除可能很快;这是你提到的我试图避免的最坏的情况@templatetypedef:谢谢;)我昨天在做一个项目的时候遇到了这个挑战,我个人觉得它真的很有趣,我想把它带到这里是个好主意!还有@Matthieu M:是的,这似乎是最大的复杂性。我希望有一个聪明的方法来解决这个问题,但是。。。无论如何,看起来我已经有了一些想法。不要考虑所有项目的线性时间,如果你能做到这一点,你可以在线性时间中插入它们,在删除每个项目时,你可以输出它(打印它),对于删除使用removeat(1),removeat(2)。。。所以您将在线性时间内输出排序列表,但这是不可能的(对于比较基方法和插入应该有某种比较来填充平衡二叉树)。@Saeed-我不明白您的意思。这并没有打破排序的O(nlgn)障碍,也没有尝试对任何东西进行排序。您能否澄清您的担忧?您是否希望在O(log(N))中插入项目,以及在O(log(N))中如何使用平衡树而不使用比较方法?如果你使用比较方法,你可以按排序的顺序输出你的项目,如果你有一些O(x)方法来插入或删除和平衡树(即n个项目的O(x)之和是O(n)),你可以通过移除O(n)中的项目来排序,我没有说你排序,但我是说平衡树的构造需要比较法,你使用的任何方法都可以用于排序。@Saeed-啊,我明白你的意思了。实际上,你不需要比较来平衡这棵树;如果您仔细想想,任何树都可以是红色/黑色树,即使节点本身没有任何特定的排序顺序。其思想是采用红/黑树的形状,并使用它按顺序存储一系列(未排序)值,方法是以这样一种方式存储它们,即按所需顺序进行顺序遍历。CLRS对此进行了讨论。顺便说一下,我不打算让这个系统在O(n)时间内工作。。。我认为这需要一些新的东西。这个结构有一个名字:顺序统计树。