Trie树Java模板

本文介绍了Trie树,又称前缀树,是一种用于存储和查找字符串的集合,利用公共前缀减少查询时间。文章详细讲解了Trie树的结构,并提供了Java代码实现,包括插入和查询操作。最后给出了LeetCode相关练习题。
摘要由CSDN通过智能技术生成

T r i e Trie Trie

欢迎关注我的公众号ACJavaBear了解更多精彩内容


1.什么是 T r i e Trie Trie

T r i e Trie Trie 树,又叫前缀树,也叫字典树,用于统计和保存大量的字符串

它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较。

简而言之, T r i e Trie Trie 树是用来存储和查找字符串的一个集合。

2. T r i e Trie Trie 树的结构

如图(图片来自于百度百科)

img

(1) 根节点 root

(2) 子节点 TrieNode

  • 该节点是否是某字符串的结尾字符 isEndtrue则是,否则不是
  • 该节点的儿子数组 TrieNode[] son,用于存储该节点的儿子
  • 以当前节点结尾的字符串出现的次数num
  • 当前结点的值 val(有时完全不需要)

(3) T r i e Trie Trie 树的几种常见操作

  • 插入
  • 查询

3. 如何用代码编写一棵 T r i e Trie Trie

以存储由小写字母构成的字符串的 T r i e Trie Trie 树为例。

(1) 创建一个类名为 T r i e Trie Trie

(2) 属性

  • 根节点 TrieNode root

  • 普通结点 TrieNode

    • 属性
      • boolean isEnd
      • TrieNode[] son
      • int num
    • 构造方法
    public TrieNode(){
        isEnd = false;
        son = new TrieNode[26];
        num = 0;
    }
    

(3) 构造方法

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

(4) 基本操作

  • 插入一个字符串
public void insert(String word){
    char[] w = word.toCharArray();
    TrieNode p = root;
    for(char c : w){
        //把'a'~'z'映射到0~25
        int u = c - 'a';
        if(p.son[u] == null) p.son[u] = new TrieNode();//没有子节点,创建子节点
        p = p.son[u];//到子节点位置
    }
    p.isEnd = true;//以当前结点结尾的字符串标记为true
    p.num++;//出现次数加一
}
  • 查询一个字符串在集合中出现了几次
public int query(String word){
    char[] w = word.toCharArray();
    TrieNode p = root;
    for(char c : w){
        int u = c - 'a';
        if(p.son[u] == null) return 0;//没有该节点,直接返回0
        p = p.son[u];
    }
    if(p.isEnd == true) return p.num;//是以此节点为结尾,返回出现次数
    return 0;
}
具体代码
public static class Trie{
    public TrieNode root;
    public Trie(){
        root = new TrieNode();
    } 
    public class TrieNode{
        boolean isEnd;
        TrieNode[] son;
        int num;
        public TrieNode(){
            isEnd = false;
            son = new TrieNode[26];
            num = 0;
        }
    }
    public void insert(String word){
        char[] w = word.toCharArray();
        TrieNode p = root;
        for(char c : w){
            int u = c - 'a';
            if(p.son[u] == null) p.son[u] = new TrieNode();
            p = p.son[u];
        }
        p.isEnd = true;
        p.num++;
    }
    public int query(String word){
        char[] w = word.toCharArray();
        TrieNode p = root;
        for(char c : w){
            int u = c - 'a';
            if(p.son[u] == null) return 0;
            p = p.son[u];
        }
        if(p.isEnd == true) return p.num;
        return 0;
    }

4.练习题

$LeetCode 208. 实现 Trie (前缀树) $

https://leetcode-cn.com/problems/implement-trie-prefix-tree/

题解如下

class Trie {

    TrieNode root; //根节点
    class TrieNode{//普通结点类
        boolean isEnd;
        TrieNode[] son;
        public TrieNode(){
            isEnd = false;
            son = new TrieNode[26];
        }
    }
    /** Initialize your data structure here. */
    public Trie() {
        root = new TrieNode();
    }
    
    /** Inserts a word into the trie. */
    public void insert(String word) {
        if(word != null && word.length() != 0){
            char[] w = word.toCharArray();
            TrieNode p = root;
            for(char c : w){
                int u  = c - 'a';
                if(p.son[u] == null) p.son[u] = new TrieNode();
                p = p.son[u];
            }
            p.isEnd = true;
        }
    }
    
    /** Returns if the word is in the trie. */
    public boolean search(String word) {
        if(word == null || word.length() == 0) return false;
        TrieNode p = root;
        char[] w = word.toCharArray();
        for(char c : w){
            int  u = c - 'a';
            if(p.son[u] == null) return false;
            p = p.son[u];
        }
        if(p.isEnd) return true;
        return false;
    }
    
    /** Returns if there is any word in the trie that starts with the given prefix. */
    public boolean startsWith(String word) {
        if(word.length() == 0 || word == null) return false;
        TrieNode p = root;
        char[] w = word.toCharArray();
        for(char c : w){
            int u = c-'a';
            if(p.son[u] == null) return false;
            p = p.son[u];
        }
        return true;
    }
}

/**
 * Your Trie object will be instantiated and called as such:
 * Trie obj = new Trie();
 * obj.insert(word);
 * boolean param_2 = obj.search(word);
 * boolean param_3 = obj.startsWith(prefix);
 */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值