【发布时间】:2014-02-12 14:39:35
【问题描述】:
所以我查看了SortedList<TKey, TValue> 的实现和Add 的实现(调用Insert 如下所示)真的让我很惊讶。
Add 方法执行明显的二分搜索来确定 KVP 应该进入的索引,但 Insert 似乎 好像可以改进 显着(当然是在更大的范围内):
private void Insert(int index, TKey key, TValue value)
{
if (this._size == this.keys.Length)
this.EnsureCapacity(this._size + 1);
if (index < this._size)
{
Array.Copy((Array) this.keys, index, (Array) this.keys, index + 1, this._size - index);
Array.Copy((Array) this.values, index, (Array) this.values, index + 1, this._size - index);
}
this.keys[index] = key;
this.values[index] = value;
++this._size;
++this.version;
}
如果我没看错,并且我保留在任何时候犯错的权利,这是一个O(2n) 操作。
在我看来,值应该用指针来实现。 有点像LinkedList 与键中的值有关,但不是链接,因为它不支持随机访问。更何况 key 只是 linked 到它的值。 get 操作不会变慢,而 remove 也不会因为我们有指针而变慢,但现在 add 操作将改为 O(n)。
有人能解释一下为什么这个决定会朝着这个方向发展吗?
【问题讨论】:
-
为什么不通过编写自己的自定义
SortedList来测试这两种方法。只有当您的版本更快时,您的问题才会有意义。 -
@L.B:你是在暗示我的大 O 可能是错的吗?在那我需要从字面上而不是理论上验证可扩展性?我不是在讽刺,只是在问。
-
@MichaelPerrenoud O(2n) 与 O(n) 相同。它们都表现出线性增长并且将平等地扩展。重要的是曲线的形状,而不是斜率。
-
查看stackoverflow.com/questions/322715/… 以获得两者之间的 Big O 比较(
ArrayList使用与此实现相同的动态大小数组)。 -
@MichaelPerrenoud 2 是复杂性分析忽略的常数因素之一。恒定因素可能很重要(尽管大哦是表达这一点的完全错误的工具)。但是,各种其他因素都会影响常数因素,包括您是否使用链表作为值以及如何布置数据。您不能忽略大多数不变的因素并声称有所改进,然后您只取消了其中一个,而没有调查其他因素是如何变化的,以及这是否会影响性能改进。
标签: c# .net data-structures