[英]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.