0
点赞
收藏
分享

微信扫一扫

Dictionary、hash桶

蒸熟的土豆 2022-01-10 阅读 119

C#版本:

添加元素:

流程:

代码:

// 其实就是一个Entry类型的数据,不过这个结构体在Dictionary内部私有
private struct Entry
{
    public int hashCode;  // key对应的哈希编码(GetHashCode(), 由下分析可知,该值最大为Int32的最大值) 
    public int next;	// 下一个元素对应的哈希值
    public TKey key;	// 这一个Entry的 key
    public TValue value;	// 这一个Entry的 value
}

public void Add(TKey key, TValue value) => this.TryInsert(key, value, InsertionBehavior.ThrowOnExisting); // .Net 6.0 grammar
// 其实和这个一样
public void Add(TKey key, TValue value){
	this.TryInsert(key, value, InsertionBehavior.ThrowOnExisting);    
}

private bool TryInsert(TKey key, TValue value, InsertionBehavior behavior)
{
    if ((object) key == null)
        throw new ArgumentNullException(nameof (key));
    if (this.buckets == null)
        this.Initialize(0);
    int num1 = this.comparer.GetHashCode(key) & int.MaxValue;
    int index1 = num1 % this.buckets.Length;
    int num2 = 0;
    for (int index2 = this.buckets[index1]; index2 >= 0; index2 = this.entries[index2].next)
    {
        if (this.entries[index2].hashCode == num1 && this.comparer.Equals(this.entries[index2].key, key))
        {
            if (behavior == InsertionBehavior.OverwriteExisting)
            {
                this.entries[index2].value = value;
                ++this.version;
                return true;
            }
            if (behavior == InsertionBehavior.ThrowOnExisting)
                throw new ArgumentException(SR.Format("An item with the same key has already been added. Key: {0}", (object) key));
            return false;
        }
        ++num2;
    }
    int index3;
    if (this.freeCount > 0)
    {
        index3 = this.freeList;
        this.freeList = this.entries[index3].next;
        --this.freeCount;
    }
    else
    {
        if (this.count == this.entries.Length)
        {
            this.Resize();
            index1 = num1 % this.buckets.Length;
        }
        index3 = this.count;
        ++this.count;
    }
    this.entries[index3].hashCode = num1;
    this.entries[index3].next = this.buckets[index1];
    this.entries[index3].key = key;
    this.entries[index3].value = value;
    this.buckets[index1] = index3;
    ++this.version;
    if (num2 > 100 && this.comparer is NonRandomizedStringEqualityComparer)
    {
        this.comparer = (IEqualityComparer<TKey>) EqualityComparer<string>.Default;
        this.Resize(this.entries.Length, true);
    }
    return true;
}

查找元素:

流程:

代码:

public bool ContainsKey(TKey key) => this.FindEntry(key) >= 0;

/*
基本变量及条件:
	this.buckets -> private int[] buckets;
	
	this.comparer -> private IEqualityComparer<TKey> comparer;
	这里主要使用这个比较器的 GetHashCode(), Equals()
	
	MaxValue 为 int System.Int32.MaxValue = 2147483647; 
    表示 Int32 的最大可能值。 此字段为常数
 	
 	this.entries ->  private Dictionary<TKey, TValue>.Entry[] entries;
 	其实就是一个Entry类型的数据,不过这个结构体在Dictionary内部私有,结构如看put(添加操作)部分  
*/
private int FindEntry(TKey key)
{
    if ((object) key == null)
        throw new ArgumentNullException(nameof (key));
    if (this.buckets != null)
    {
        int num = this.comparer.GetHashCode(key) & int.MaxValue;
        for (int index = this.buckets[num % this.buckets.Length]; index >= 0; index = this.entries[index].next)
        {
            if (this.entries[index].hashCode == num && this.comparer.Equals(this.entries[index].key, key))
                return index;
        }
    }
    return -1;
}
举报

相关推荐

0 条评论