字典树(Trie树/前缀树)

什么是Trie树

Trie树,也称为字典树或前缀树,是一种用于快速检索字符串数据集中的键的树形数据结构。Trie树的核心思想是利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,从而达到高效检索的目的。

Trie树的特点

  1. 结构特点

    • 节点存储字符:每个节点存储一个字符,从根节点到叶子节点的路径表示一个完整的字符串。
    • 多叉树:每个节点可以有多个子节点,每个子节点对应一个字符。
    • 根节点为空:根节点通常不存储任何字符,只是一个起点。
  2. 高效检索

    • 前缀匹配:Trie树可以高效地进行前缀匹配,例如查找所有以某个前缀开头的字符串。
    • 插入和查找时间复杂度:插入和查找的时间复杂度为O(m),其中m是字符串的长度,与字典中的字符串数量无关。
  3. 空间优化

    • 共享前缀:Trie树通过共享公共前缀来节省空间,多个字符串的相同前缀只存储一次。
    • 内存消耗:相比于哈希表,Trie树在处理大量具有公共前缀的字符串时,可以节省更多的内存。
  4. 应用广泛

    • 自动补全:在搜索引擎、代码编辑器等场景中,用于自动补全和提示。
    • 拼写检查:用于拼写检查和纠正。
    • IP路由表:在网络路由中,用于快速查找最长前缀匹配的路由。

Trie树的基本操作

  1. 插入(Insert)

    • 从根节点开始,逐字符检查字符串。
    • 如果当前字符不存在于当前节点的子节点中,则创建一个新的节点。
    • 移动到下一个字符,重复上述过程,直到字符串结束。
    • 在字符串的最后一个字符对应的节点上标记为结束节点。
  2. 查找(Search)

    • 从根节点开始,逐字符检查字符串。
    • 如果当前字符存在于当前节点的子节点中,则移动到下一个字符。
    • 如果字符串结束时,对应的节点被标记为结束节点,则表示字符串存在于Trie树中。
  3. 前缀匹配(Prefix Match)

    • 从根节点开始,逐字符检查前缀。
    • 如果前缀的所有字符都存在于Trie树的路径中,则表示存在以该前缀开头的字符串。
    • 可以继续遍历以该前缀结尾的节点下的所有子节点,找到所有匹配的字符串。

示例代码

简单的Trie树的Java实现:

import java.util.HashMap;
import java.util.Map;

class TrieNode {
    Map<Character, TrieNode> children;
    boolean isEndOfWord;

    public TrieNode() {
        children = new HashMap<>();
        isEndOfWord = false;
    }
}

public class Trie {
    private TrieNode root;

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

    // 插入一个单词
    public void insert(String word) {
        TrieNode current = root;
        for (char l : word.toCharArray()) {
            current = current.children.computeIfAbsent(l, c -> new TrieNode());
        }
        current.isEndOfWord = true;
    }

    // 搜索一个单词
    public boolean search(String word) {
        TrieNode current = root;
        for (char l : word.toCharArray()) {
            TrieNode node = current.children.get(l);
            if (node == null) {
                return false;
            }
            current = node;
        }
        return current.isEndOfWord;
    }

    // 判断一个前缀是否存在
    public boolean startsWith(String prefix) {
        TrieNode current = root;
        for (char l : prefix.toCharArray()) {
            TrieNode node = current.children.get(l);
            if (node == null) {
                return false;
            }
            current = node;
        }
        return true;
    }

    public static void main(String[] args) {
        Trie trie = new Trie();
        trie.insert("apple");
        System.out.println(trie.search("apple"));   // 返回 true
        System.out.println(trie.search("app"));     // 返回 false
        System.out.println(trie.startsWith("app")); // 返回 true
        trie.insert("app");
        System.out.println(trie.search("app"));     // 返回 true
    }
}

总结

Trie树是一种高效的字符串检索数据结构,通过共享公共前缀来节省空间,适用于需要快速前缀匹配和字符串查找的场景。它的插入、查找和前缀匹配操作都具有较低的时间复杂度,使其在许多应用中表现出色。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值