c# - 为什么我们在哈希算法中有一个额外的桶数组?

标签 c# .net algorithm hash

我一直在逐步完成 .net 框架的 Hashset 的实现,我对它的实现有点困惑。这是 Contains 方法:

    private int[] m_buckets;
    private Slot[] m_slots;

public bool Contains(T item) {
        if (m_buckets != null) {
            int hashCode = InternalGetHashCode(item);
            // see note at "HashSet" level describing why "- 1" appears in for loop
            for (int i = m_buckets[hashCode % m_buckets.Length] - 1; i >= 0; i = m_slots[i].next) {
                if (m_slots[i].hashCode == hashCode && m_comparer.Equals(m_slots[i].value, item)) {
                    return true;
                }
            }
        }
        // either m_buckets is null or wasn't found
        return false;
    }


internal struct Slot {
        internal int hashCode;      // Lower 31 bits of hash code, -1 if unused
        internal T value;
        internal int next;          // Index of next entry, -1 if last
    }

我理解了第一部分,获取item的hash code。接下来开始循环并从哈希码生成合适的索引。但随后它使用此索引从整数数组中检索一个值,然后使用该值检查值的哈希码和值本身是否相同。为什么是这样?另外,我无法理解 .next 属性,为什么有必要存储此信息?

最佳答案

多个对象可能具有相同的 hashCode % m_buckets.Length 值,即使它们具有不同的 hashCode 值。不同的对象也可能具有相同的 hashCode 值(即使这不太可能)。

解决方法是将所有具有相同 hashCode % m_buckets.Length 值的对象存储在一个数组中,然后在该数组中搜索适当的元素。它比较 hashCode 值和对象本身的原因是 hashCode 的比较比对象本身的比较快。通过首先对哈希码进行廉价检查,我们可以避免对对象进行昂贵的检查。

存储下一个值,以便可以枚举散列为单个值的元素。

关于c# - 为什么我们在哈希算法中有一个额外的桶数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28439590/

相关文章:

c# - 使WinForms富文本框忽略 "CTRL + >"和 "CTRL + <"热键

c# - VS2010 将资源文件引用更改为 4.0 版,尽管目标是 3.5 Framework

c# - 通过 SyntaxFactory (Roslyn) 构造 NameOf 表达式

.net - 如何从我的 DLL 访问 MainForm 中的函数

c# - 无法加载文件或程序集 log4net

c - 迭代后序遍历在树的根节点中断

c# - 使用自定义类 c# 反序列化来自 API 的响应

algorithm - 最大二分匹配(ford-fulkerson)

algorithm - 主成分初始化如何确定自组织映射中映射向量的权重?

c# - StreamReader/StreamWriter 的基本多线程