我试图从复杂性的角度更好地理解哈希表和字典在 C# 中的工作方式(但我猜语言不是一个重要因素,这可能只是一个理论问题)。
我知道Add
a的方法Dictionary
应该是 O(1) 如果Count
小于容量(这很明显)。
但是,让我们看一下该代码:
public class Foo {
public Foo() { }
public override int GetHashCode() {
return 5; //arbitrary value, purposely a constant
}
}
static void Main(string[] args) {
Dictionary<Foo, int> test = new Dictionary<Foo,int>();
Foo a = new Foo();
Foo b = new Foo();
test .Add(a, 5);
test .Add(b, 6); //1. no exception raised, even though GetHashCode() returns the same hash
test .Add(a, 10); //2. exception raised
}
我知道在幕后有哈希冲突,1.
并且可能有一个单独的链接来处理它。
但是,在2.
参数处引发异常。这意味着 Dictionary 内部会在确定其哈希值后跟踪插入的每个键。这也意味着每次我们向字典中添加条目时,它都会使用该方法检查键是否尚未插入equals
。
我的问题是,如果它检查已经插入的键,为什么它看起来应该是 O(n) 复杂度时被认为是 O(1) 复杂度?