扩展ArrayList并实现IEnumerable - 有更好的方法吗?

时间:2014-11-30 01:33:36

标签: c# performance algorithm inheritance multiple-inheritance

我需要一种实现IEnumerable接口的数据类型,但也允许在固定时间内删除/插入任意数量的元素。

此外,数据类型必须允许对已知元素的持续访问时间。基本上我需要的是一个C89风格的双链表,它实现了IEnumerable。

我的一个要求是我不会多次迭代数据。

我考虑(并且正在努力)创建一个扩展ArrayList并实现IEnumerable接口的类,但我关注的是更简洁或更好的方法。

这一切都是因为我正在处理的代码的输入变量之一是IEnumerable类型(我无法改变它)。

我的问题有两个:

  1. 有没有办法实现我所描述的功能,而无需创建单独的类或迭代每个元素?
  2. 如果1的答案为否,那么我在创建我所描述的课程时应该采取哪些主要步骤?
  3. 谢谢!

    ------- -------编辑

    此算法的主要目标是根据特定标准将元素组合在一起(专有,因此没有代码,抱歉!!!)。为此,该算法创建一个单独的列表,并为每个父母"记录创建,复制(或(编辑)理想地移动,这更快!)由算法指定的记录作为父节点的子节点。很抱歉没有更清楚这一点;我昨晚2点在美国东部时间下午2点工作。

3 个答案:

答案 0 :(得分:3)

感谢Enigmativity向我展示这是不可能的。

由于索引要求元素保持有序并且不删除它们,因此重新索引列表将需要N(N-k)时间。 (其中N是列表的长度,k是元素的数量)。使用严格链接列表解决方案仍然需要k时间来迭代所有k个元素。

我看到的唯一解决方案是实现一个类型,该类型使用C89样式的双向链表以及sizeof来跳过要移除到下一个元素的k个元素(以便保持列表的完整性) )。这将允许N个时间来处理列表。它还需要2N内存。

值得指出的是,这样的解决方案必须利用"不安全" C#关键字。这意味着调用此方法的任何方法也必须标记为不安全,一直到main。请参阅here,了解为什么这是一条相当糟糕的路线。

答案 1 :(得分:1)

虽然它不符合您的固定时间要求,但order statistic tree基于B+ tree的某些内容会有对数时间插入和删除。查找元素的索引并按索引查找元素也是对数时间操作。谷歌的五秒没有透露任何明显的开源.NET实现的订单统计树,但编写自己的应该不是非常困难。您可以决定不使用B +树严格支持集合,但我们的想法是仍然可以进行顺序访问。

这样的类会正确实现IList<T>,这当然来自IEnumerable<T>。听起来你知道IEnumerable<T>本身可以保证你很少。如果您的代码传递的IEnumerable<T>实际上不是您的order-statistic-tree类,则必须从IEnumerable<T>创建order-statistic树,其中(我认为)是{{} 1}}操作。我假设O(n ln n)是有限的,也是not guaranteed。不过,听起来你并不关心无限集合。除了IEnumerable<T>的要求之外,您还需要为插入和删除添加特定的范围操作(如IList<T>),这些操作将针对您的用例进行优化。

此解决方案的优点是不需要List<T>.AddRange(IEnumerable<T>),并且它没有直接显示@HugoRune在他的答案评论中提到的“但一旦列表有间隙”问题。

另外,不要费心继承unsafe。如果要使用ArrayList或任何其他集合实现来存储项目,请通过委派给集合实现的内部实例来执行此操作。

答案 2 :(得分:0)

我仍然不确定这个c89样式链表应该做什么;除非在非常有限的情况下,否则在O(1)中插入和删除多个元素等一些事情似乎是不可能的。

尽管如此,使用指针操作将这样的数据结构转换为没有指针的托管c#结构很简单:分配一个数组并假装它的数组索引是指针。

所以不是malloc(100 *Size_Of_Node) 你会做nodes[]= new Node[100];

并在每个节点内部,而不是Node* nextNode* prev,您将存储int nextint prev,然后通过{{1}访问相邻节点}。

这允许您在访问每个元素时以一个额外的间接层为代价进行直接指针操作的所有可能性。

如果您使用Node nextNode = nodes[currentNode.next]而不是数组作为后备存储,您也可以根据需要增加其大小,而不是事先分配它。

为了在需要IEnumerable的地方使用这个自定义C89样式链表,你需要做的只是为这个结构实现IEnumerable(不完整):

List<Node>