Java 使用嵌套哈希映射实现TRIE?

Java 使用嵌套哈希映射实现TRIE?,java,algorithm,data-structures,hashmap,trie,Java,Algorithm,Data Structures,Hashmap,Trie,使用嵌套的哈希映射创建TRIE有什么好处 例如,让我们有一个嵌套的哈希映射,其中每个映射只有一个字符的键。因此,对于单词“Dog”,我们会有类似于myHashMap['d']['o']['g']['*']=True的东西。 末尾的“*”表示条目的结尾 在书中,我从未见过这种方法,而是“经典”节点类。为什么? 如果每个节点只有256个条目,为什么你会考虑一个哈希图?如果将hashmap变小,则会增加较低节点上发生冲突的风险,并且这些良好的属性将消失。。。如果你让它动态化,你会得到所有的管理开销 当

使用嵌套的哈希映射创建TRIE有什么好处

例如,让我们有一个嵌套的哈希映射,其中每个映射只有一个字符的键。因此,对于单词“Dog”,我们会有类似于
myHashMap['d']['o']['g']['*']=True的东西。
末尾的“*”表示条目的结尾


在书中,我从未见过这种方法,而是“经典”节点类。为什么?

如果每个节点只有256个条目,为什么你会考虑一个哈希图?如果将hashmap变小,则会增加较低节点上发生冲突的风险,并且这些良好的属性将消失。。。如果你让它动态化,你会得到所有的管理开销

  • 当你声明你的嵌套hashmap时,你会把它做多深 如果它不是一个固定的深度,那么您只需要使用hashmap作为节点来复制一个“节点”方法
  • hashmap->hashmap->hashmap将占用更多的空间,并且比仅仅使用字符串的散列要慢
  • Hashmaps没有排序-因此现在您有了一个未排序的映射,而这实际上不是trie

  • 这是一个很好的问题,也是我目前正在思考的问题

    Glenn的回答没有考虑到Trie(或前缀树,换个名字)的前缀存储性质。如果您只需要一个字典,那么哈希表是一个更好的选择,但是如果您想做一些自动完成样式的事情,那么Trie是理想的选择。对于Trie,我也不了解它需要排序

    我想您提到的“经典”方法是使用字符索引数组O(1)查找来引用任何节点的子节点。这对于小字母表来说是快速且节省空间的,但正如您所观察到的,对于非常大的字符集(Unicode),空间很快就会变得不可用

    您提到的另一种方法是在每个节点上都有一个HashMap,将每个字符映射到子节点。保留索引数组的恒定查找时间(假设是真正的哈希实现),并且希望每个节点不使用数千字节来存储空字符槽

    在我看来这是一场胜利,所以我也想知道为什么我没有经常提到它

    一个混合方法,我认为,如果你知道前面的整个字母表,把char ->数组索引(连续索引到你的子数组)中的哈希映射保持在两个世界的最好位置。只需预先扫描字典,告诉Trie您将在构建时使用哪些unicode字符。

    Map<Character, TrieMap<K, V>> children = new TreeMap<>();
    
    因此,我通过确保无子节点不会持有浪费的空
    Map
    (尽管我可以很容易地使用
    Collections.emptyMap()
    )来进一步减少内存占用。

    什么是“经典节点类”?例如,wikipedia在没有指定节点的内部表示的情况下定义了尝试,并实际讨论了几种这样的表示。
    /**
     * Map each character to a sub-trie.
     *
     * Could replace this with a 256 entry array of Tries but this will handle multi-byte character sets and I can discard
     * empty maps.
     *
     * Maintained at null until needed (for better memory footprint).
     *
     */
    private Map<Character, TrieMap<K, V>> children = null;
    
    ....
    
    /**
     * Create a new set of children.
     *
     * I've always wanted to name a method something like this.
     */
    private void makeChildren() {
      if (children == null) {
        // Use a TreeMap to ensure sorted iteration.
        children = new TreeMap<>();
      }
    }