【发布时间】:2014-09-07 00:04:48
【问题描述】:
来自SortedSet<T>.GetEnumerator 文档:
这个方法是一个O(1)操作
来自SortedDictionary<K, V>.GetEnumerator 文档:
此方法是 O(log n) 运算,其中 n 为计数。
考虑到SortedDictionary<K, V> 在内部实现为SortedSet<KeyValuePair<K, V>,这两种说法是否都成立?我检查了SortedDictionary 类的GetEnumerator 代码——它直接使用SortedSet 的枚举器。我注意到SortedSet 的枚举器实现,在我看来它确实具有 O(log n) 特性(这里是代码):
public SortedSet<T>.Enumerator GetEnumerator()
{
return new SortedSet<T>.Enumerator(this);
}
//which calls this constructor:
internal Enumerator(SortedSet<T> set)
{
this.tree = set;
this.tree.VersionCheck();
this.version = this.tree.version;
this.stack = new Stack<SortedSet<T>.Node>(2 * SortedSet<T>.log2(set.Count + 1));
this.current = (SortedSet<T>.Node) null;
this.reverse = false;
this.siInfo = (SerializationInfo) null;
this.Intialize();
}
private void Intialize()
{
this.current = (SortedSet<T>.Node) null;
SortedSet<T>.Node node1 = this.tree.root;
while (node1 != null)
{
SortedSet<T>.Node node2 = this.reverse ? node1.Right : node1.Left;
SortedSet<T>.Node node3 = this.reverse ? node1.Left : node1.Right;
if (this.tree.IsWithinRange(node1.Item))
{
this.stack.Push(node1);
node1 = node2;
}
else
node1 = node2 == null || !this.tree.IsWithinRange(node2.Item) ? node3 : node2;
}
}
这是否意味着文档有误,SortedSet<T>.GetEnumerator 是 O(log n)? 没有太多关于 GetEnumerator 调用的性能,只是确保我是否理解正确。
【问题讨论】:
-
嗯,这看起来肯定是一个文档错误。
-
您需要检查 SortedDictionary 的代码以了解发生了什么。它会调用 SortedSet log(n) 次吗?如果是这样,文档是正确的。
-
@user2880486 SortedDictionary 直接调用 SortedSet 枚举器。由于在内部它被实现为
SortedSet<KeyValuePair<K,V>>。不,它不会调用枚举器日志 n 次。此外,我的问题不是SortedDictionary 为O logn,而是SortedSet 为O 1。这就是为什么我只发布了SortedSet 的枚举器代码。从代码中看起来不是 O 1 而是 O logn。 -
感谢 MSDN 上有关我们主题的反馈。我已经修复了我们latest version of the documentation 中的文档错误。不幸的是,我无法修复同一主题的 4.0 版本。
标签: .net big-o asymptotic-complexity sortedset sorteddictionary