leetcode_208 Implement Trie(Prefix Tree)

来源:互联网 发布:闪电下单软件 编辑:程序博客网 时间:2024/06/05 17:12

题目分析:

  • 实现字典树,包含其插入、查找以及前缀查找等方法。可以假设所有输入都只包含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);        }};
0 0
原创粉丝点击