leetcode_208 Implement Trie(Prefix Tree)

题目分析:

  • 实现字典树,包含其插入、查找以及前缀查找等方法。可以假设所有输入都只包含a-z字符。

解题思路:

  • 字典树简介

    字典树(Trie Tree),又名前缀树,使一种用于快速检索的多叉树。主要用于字符串统计和查找等功能。

    字典树性质

    1)根节点不包括字符,除根节点外每个节点包含一个字符;

    2)从根节点到某一节点,路径上经过的字符串连接起来,为该节点对应的字符串;

    3)每个节点的所有子节点包含的字符都不相同。

    实现结构分析

    1)结构题中,val为字典树中某个节点对应的字符;

    2)子节点简单使用长度为26的数组实现;

    3)isWord标记从根节点到该节点是否表示一个单词,还是单词的前缀。

    4)主要操作包括插入、查找等。

  • 实现程序

    // 字典树节点结构 
    class TrieNode
    {
        public:
            char var;                 // Trie Tree节点字符 
            bool isWord;              // 判断该Trie Tree的节点是否对应一个单词 
            TrieNode *children[26];   // Trie Tree节点的子节点  
            TrieNode()                // 初始化TrieNode
            {
                var = 0;
                isWord = false;
                memset(children, 0x0 , sizeof(TrieNode*) * 26);
            }
            TrieNode(char c)          // 使用特定字符创初始化Trie Tree节点 
            {
                var = c;
                isWord = false;
                memset(children, 0x0, sizeof(TrieNode *) * 26);
            }
    };
    // Trie Tree类 
    class Trie
    {
        public:
            TrieNode *root;           // Trie Tree根节点 
            Trie()                    // 创建空的Trie Tree 
            {
                root = new TrieNode();
            }
            void insert(string word)  // 在Trie Tree中插入一个单词 
            {
                TrieNode *pNode = root;
                if (word.length() <= 0)
                {
                    return ;
                }
                for (int i = 0; i < word.length(); i++)    // 遍历单词所有字符 
                {
                    char c = word[i];
                    // 单词中字符不存在Trie Tree中,则创建对应的节点
                    if (pNode->children[c - 'a'] == 0)         
                    {
                        TrieNode *pNew = new TrieNode(c);
                        pNode->children[c - 'a'] = pNew;
                    }
                    pNode = pNode->children[c - 'a'];      // 更新查找节点 
                }
                pNode->isWord = true; // 标记为单词 
            } 
    
            bool search(string word)  // 在Trie Tree中查找一个单词 
            {
                TrieNode *pNode = root;
                if (word.length() <= 0)
                    return true;
                for (int i = 0; i < word.length(); i++)    // 遍历单词所有字符 
                {
                    char c = word[i];
                    pNode = pNode->children[c - 'a'];
                    // 出现某个字符不存在,则返回退出,否则继续下一个查找 
                    if (pNode == NULL)                     
                        return false; 
                }
                // 返回最后对应的字符是否为单词,从而返回是否存在标志 
                return pNode->isWord; 
            }
            bool startsWith(string prefix)    //返回一个单词是否存在前缀  
            {
                TrieNode *pNode = root;
                if (prefix.length() <= 0)     // 特殊情况处理 
                    return true;
                for (int i = 0; i < prefix.length(); i++)  // 遍历整个前缀 
                {
                    char c = prefix[i];
                    pNode = pNode->children[c - 'a'];
                    // 如果前缀中某个单词不存在,返回不存在并结束,否则继续判断 
                    if (pNode == NULL)         
                        return false;
                }
                return true; 
            } 
            void freeTrieNode(TrieNode *pNode) // 销毁一颗Trie Tree 
            {
                if (pNode == NULL)
                    return ;
                // 遍历所有字符,递归销毁该字符及其对应的子Trie树 
                for (int i = 0; i < 26; i++)   
                {
                    TrieNode *pChild = pNode->children[i];
                    if (pChild != NULL)
                    {
                        freeTrieNode(pChild);
                    }
                }
                free(pNode);
            }
            ~Trie()                   // Trie Tree析构函数 
            {
                freeTrieNode(root);
            }
    };
    

你可能感兴趣的:(LeetCode)