有效地散列树

时间:2017-01-30 20:48:09

标签: java algorithm hash

我经常在大森林中搜索许多不同的树片段,并且希望搜索的“相等检查”部分比O(N)时间更快。这个想法是“哈希”树片段并将冲突视为平等。

我的树结构是一个标准的Node对象,它有一个int值字段和一个children字段。我希望植根于某个节点的树的哈希值仅依赖于它的子节点,并且给定子节点的哈希码已经改变,可以将相对便宜的更新应用于子节点的父节点的哈希码。如果我们可以实现O(1)更新操作,那么叶节点处的值更改将导致对树的O(log n)链反应。

我已阅读以下问题:Hashing a Tree Structure

给出了一个很好的答案。但是,我遇到了算法的实施问题。由于字符串在Java中是不可变的,子节点中的更新将转换为父节点中的O(N)哈希码更新操作。如果我误解了上面的答案,请在这里纠正我。

我正在寻找什么是可能的哈希函数?

2 个答案:

答案 0 :(得分:0)

如果我理解正确,如果你只是想检查两棵树的相等性,你就不需要哈希。是!如果要将树放在某个集合数据结构中并尝试使用某些键访问它们,则需要良好的散列函数。 “这个想法是”散布“树片段并将碰撞视为平等” 这不是正确的陈述,你不应该这样做。相同的哈希码通常并不意味着相等。平等的概念与此无关 函数哈希。散列是为了更快地检索/访问某些集合(如散列映射或散列表)中的元素。

答案 1 :(得分:0)

我发现问题非常有趣。我们可以尝试为每个节点创建一个唯一的整数,该整数由该节点下面的子树计算。它不会对你有所帮助,因为你有森林而不是二叉树。但是对于二叉树,我认为对左右儿童进行不同的权衡将有助于避免镜像树的相同哈希。

class Node{ 
    int value;
    List<Node> children;

    @Override
    public int hashCode(){
         int childCount = children.size();
         int sum = 0;
         for Node child : children:
             sum += child.hashCode();
         int hashCode = childCount * 2^31 + value * 2^23 + sum * 2^13;

         return hashCode;
    }
}

我觉得这会给你所需的哈希函数。这可能不是无冲突哈希。它将排除大多数不相等的子树。一旦获得子树的相同哈希,就可以执行相等性检查以确认。这肯定会减少大部分计算。