Trie 树(前缀树)

一、Trie 树是我一直想看却一直拖着没看的数据结构。主要应用的思想是通过构建树结构,使得前缀相同的字符串可共享前缀序列,一旦构建好树结构后,便可实现快速检索。

适用场景:1)找到所有前缀相同的字符串    2)以字典序枚举数据集中的每个字符串。

哈希表在上述两种场景下会有大量的哈希碰撞(hash collisions)且搜索的时间复杂度很高(最差情形下为 O(n),n为插入的键值数)。故相较于哈希表,Trie可通过存储相同前缀的字符串节省更多的空间,故搜索的时间复杂度仅为O(m), m为键长(即字符串长度)

二、主要的应用有:构建字典(查询某个单词是否在字典中)、自动纠正语法错误、自动补齐单词、IP地址路由选择等。

1)根节点的特点

1. Trie为有根树,根节点为空,不表示任何字符

2. 每个节点最多有R个孩子(若字符串中每个字符取值为‘a’~‘z’,则R=26),第i个孩子表示字母表中的第i个字符

2)插入元素

依次遍历字符串中的每个元素,若该元素存在,继续遍历下一元素;否则,插入一新的节点。

3)查找某字符串是否存在

与2)类似,依次遍历字符串中的每个元素,若该元素存在,继续遍历下一元素;否则,返回false。

例题:LeetCode 208. Implement Trie

代码如下:

class TrieNode{
public:
    char var;   //该节点对应的字符
    bool isword;        //标记从根节点到该节点是否表示一个单词或另一单词的前缀
    TrieNode* child[26];    //子节点用一个数组表示,实现简单但耗内存
    // Initialize the data structure
    TrieNode()
    {
        var = 0;
        isword = false;
        memset(child, 0, sizeof(child));
    }
    TrieNode(char c)
    {
        var = c;
        isword = false;
        memset(child, 0, sizeof(child));
    }
    
};

class Trie {
public:
    /** Initialize your data structure here. */
    Trie() {
        root = new TrieNode();
    }
    
    /** Inserts a word into the trie. */
    void insert(string word) {      
        if(word.length()<=0) return;
        TrieNode *pNode = root;
        for(int i=0; i<word.length(); ++i)
        {
            char c = word[i];
            if(pNode->child[c-'a'] == 0)
            {
                TrieNode *pNew = new TrieNode(c);
                pNode->child[c-'a'] = pNew;
            }
            pNode = pNode->child[c-'a'];
        }
        pNode->isword = true;
    }
    
    /** Returns if the word is in the trie. */
    bool search(string word) {
        TrieNode *pNode = root;
        if(word.length()<=0) return true;
        for(int i=0; i<word.length(); ++i)
        {
            char c = word[i];
            pNode = pNode->child[c-'a'];
            if(pNode==NULL) return false;
        }
        return pNode->isword;
    }
    
    /** Returns if there is any word in the trie that starts with the given prefix. */
    bool startsWith(string prefix) {      
        if(prefix.length()<=0) return true;
        TrieNode *pNode = root;
        for(int i=0; i<prefix.length(); ++i)
        {
            char c = prefix[i];
            pNode = pNode->child[c-'a'];
            if(pNode==NULL) return false;
        }
        return true;
    }
private:
    TrieNode *root;
};

/**
 * Your Trie object will be instantiated and called as such:
 * Trie obj = new Trie();
 * obj.insert(word);
 * bool param_2 = obj.search(word);
 * bool param_3 = obj.startsWith(prefix);
 */

参考链接: https://leetcode.com/problems/implement-trie-prefix-tree/solution/

                  https://blog.youkuaiyun.com/sunao2002002/article/details/46661761

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值