繁体   English   中英

复制操作的大O标记

[英]Big O notation for a copy operation

我遇到了一些肯定可以改进的代码,但我想知道我的改进的Big-O表示法。

他们的原始代码在数组中添加了一个元素,每次执行此操作时,都会创建一个新的n + 1数组,并复制旧数组,如下所示:

public MyType GetNewType()
{
    MyType[] tempTypes = new MyType[_types.Count + 1];
    _types.CopyTo(tempTypes, 0);
    _types = tempTypes;

   _types[types.Count - 1] = new MyType();
   return _types[types.Count - 1];
}

据我所知,这将是一个O(n)操作。 因此,我将其重写如下:

private int _currentIndex; //initialized in the constructor

public MyType GetNewType()
{
    if (_types.Length == _currentIndex)
    {
        MyType[] tempTypes = new MyType[_types.Length + 10];
        _types.CopyTo(tempTypes, 0);
        _types = tempTypes;
    }

   _types[_currentIndex] = new MyType();
   _currentIndex++;

   return _types[_currentIndex - 1];
}

这些更改的结果是否意味着该函数现在将以O(n / 10)运行,因为它仅需要每10次调用执行一次复制操作? 还是不是那么好用?

这是常见且良好的优化。 通常称为“摊销固定时间”,这意味着在大多数情况下,添加单个元素为O(1),除非不是。 实现者通常会将数组的大小加倍,或者至少乘以1.5,而不是仅添加十个元素。

也就是说,C#具有一些非常可爱的内置列表类,它们可以自动为您完成所有这些操作,并且在可能的情况下,使用它们比使用裸数组更可取。

用大O表示法, (n/10)复杂度将是O(n)因为它并不关心这么小的常数。

仅当每次用完免费项目时,如果数组大小加倍,摊销固定时间方可使用! 如果不是,则平均大O表示法将始终为O(n)。

每当列表计数等于容量时,C#List实现都会使数组的大小加倍。

为了使插入方法的平均值为O(1),您需要执行以下操作:

MyType[] tempTypes = new MyType[Math.Max(8, _types.Length * 2)];

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM