字典树Trie

231 阅读2分钟

字典树介绍

字典树 (Trie),又称单词查找树、前缀树,是一种树形结构,是一种哈希树的变种。在统计、排序和保存大量的字符串(但不仅限于字符串)是具有更小的时间复杂度,因此可以应用于搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。

image.png

性质:

  1. 根节点不包含字符,除根节点外每一个节点都只包含一个字符。
  2. 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
  3. 每个节点的所有子节点包含的字符都不相同。

字典树java实现

实现了以下功能:

  1. 向字典树中插入数据
  2. 获取所有插入字符串的 最长公共前缀
class TrieNode {
    String content; // 存储的内容
    int count; // 节点被使用的次数
    Map<String, TrieNode> childNode;

    TrieNode(String content) {
        this.content = content;
        this.childNode = new HashMap<>();
        this.count = 1;
    }
}

class Trie {
    TrieNode root; // 字典树根节点
    int strCount; // 字典树存储的字符数

    Trie() {
        root = new TrieNode("");
    }

    /**
     * 将字符串插入字典树中
     * 
     * @param str
     */
    void add(String str) {
        TrieNode cur = root;

        this.strCount++;
        if (str.equals("")) {
            singleAdd(cur, str);
            return;
        }

        for (int i = 0; i < str.length(); i++) {
            cur = singleAdd(cur, str.substring(i, i + 1));
        }
    }

    TrieNode singleAdd(TrieNode node, String s) {
        if (!node.childNode.containsKey(s)) {
            TrieNode newNode = new TrieNode(s);
            node.childNode.put(s, newNode);
            return newNode;
        }
        TrieNode node1 = node.childNode.get(s);
        node1.count++;

        return node1;
    }

    /**
     * 获取最长公共前缀:查找从根节点开始,子节点数量一直为1的节点数据,并统计其子节点的内容组成String
     * 
     * @return
     */
    String getLongestCommonPrefix() {
        TrieNode cur = root;

        String result = "";
        while (true) {
            if (cur.childNode.size() != 1) {
                break;
            }

            TrieNode n = cur.childNode.values().stream().collect(Collectors.toList()).get(0);
            if (n.count != this.strCount) {
                break;
            }

            result = result + cur.childNode.keySet().stream().collect(Collectors.toList()).get(0);
            cur = n;
        }
        return result;
    }
}

leetcode题型

获取最长公共前缀:链接