前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >动画Trie树

动画Trie树

作者头像
ACM算法日常
发布2021-07-16 15:56:18
3750
发布2021-07-16 15:56:18
举报
文章被收录于专栏:ACM算法日常ACM算法日常

Trie树也称之为前缀树,适合处理前缀匹配问题。也因为每一个节点都存储26个字母,也称之为字典树,发明Trie树的人喜欢把这个单词读成/ˈtriː/tree,其他人喜欢读成/ˈtraɪ/ "try"。

本篇是一个入门介绍,后面有动画。

前缀树每个节点有2个属性:一个是26个子孩子的数组,一个是是否是结尾字符。为了便于理解,一起来看下leetcode 208题,算是Trie树的裸题。

题目:

请你实现 Trie 类:

Trie() 初始化前缀树对象。

void insert(String word) 向前缀树中插入字符串 word 。

boolean search(String word) 如果字符串 word 在前缀树中,返回 true(即,在检索之前已经插入);否则,返回 false 。

boolean startsWith(String prefix) 如果之前已经插入的字符串 word 的前缀之一为 prefix ,返回 true ;否则,返回 false 。

题解

构造函数中初始化根节点,Trie*孩子节点数组初始化为0,结束标识设置为0。

插入函数从根节点开始查找,如果字符不存在,就创建一个新的Trie节点,继续遍历单词字符,创建过程很像插入了一个单词链表。

搜索函数和插入类似,遍历节点,如果不存在子孩子则返回失败,如果遍历完成,还需要保证最后一个字符的结束标识为1。

前缀函数和搜索类似,不过不需要关心结束标识。

Trie动画

源代码

代码语言:javascript
复制
class Trie {
public:
    Trie* c [26];
    char v :1; //结束标识
    /** Initialize your data structure here. */
    Trie() {
        memset(c, 0, sizeof(c));
        v = 0;
    }

    Trie* searchPrefix(string & prefix) {
        Trie* p = this;
        for(char &ch : prefix){
            char index = ch-'a';
            if(!p->c[index]){
                return 0;
            }
            p = p->c[index];
        }
        return p;
    }
    
    /** Inserts a word into the trie. */
    void insert(string word) {
        Trie* p = this;
        for(char &c:word){
            char index = c-'a';
            if(p->c[index] == 0){
                p->c[index] = new Trie();
            }
            p = p->c[index];
        }
        p->v = 1;
    }
    
    /** Returns if the word is in the trie. */
    bool search(string word) {
        Trie* v = searchPrefix(word);
        return v && v->v;
    }
    
    /** Returns if there is any word in the trie that starts with the given prefix. */
    bool startsWith(string prefix) {
        return searchPrefix(prefix);
    }
};

总结

Trie树的关键点在于像创建链表一样创建每一个单词,每个单词的最后一个字符节点设置结束标识。每个节点有26个孩子节点,所以Trie树会比较耗费内存。

DAT树

为了解决Trie树占用内存过大问题,三个日本人设计了一种特殊的数据结构,用双数组存储Trie树信息,这个设计极大的减少了内存占用问题,DAT树是Trie树内存的1%左右,在实际大规模应用中,基本上都需要使用DAT进行优化。极简笔记的中文分词就是使用的DAT,内存占用非常小。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-06-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 ACM算法日常 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目:
  • 题解
  • Trie动画
  • 源代码
  • 总结
  • DAT树
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档