208. 实现 Trie (前缀树)

字典树(前缀树):

1. 定义前缀树结构:

struct Node{
        char dir;
        bool wordend;    // 用于记录是否是一个单词的结尾
        struct Node* child[26];   // 用于存储指向下一个字符的指针
};

主要包含三个部分,当前节点表示的字母,当前节点是否是单词结尾,以及指向子节点的指针,26个代表每个字母后面可以接任意字母

2. 字典树的插入操作(一开始就查看子节点,是因为根节点为空节点,不存储字母)

      对插入单词进行遍历 

(1)如果当前字母存在子节点中,那么进入子节点,继续遍历,进入子节点

(2)如果当前字母不再子节点中,那么新建子节点,并将该字母传入给子节点,并进入子节点

   (3) 循环执行插入(1)(2)直到单词结尾处,将单词结尾处的子节点wordend标记为true,表示单词结尾

3. 字典树的查询操作

    对查询单词循环遍历,挨个查询单词中的字母

(1)如果当前字母在子结点中,那么进入子节点,如果不在子结点中(子节点为NULL)那么没有该单词,返回false

(2)如果遍历到单词结尾的字母,存在于子结点中并且该子节点的wordend=true表名该单词在树中,返回true,其他情况皆为false

4. 字典树的前缀查询

   与3相同,只不过不再需要判断是否是单词结尾,如果有则返回true

代码如下:

class Trie {
public:
    struct Node{
        char dir;
        bool wordend;    // 用于记录是否是一个单词的结尾
        struct Node* child[26];   // 用于存储指向下一个字符的指针
    };
    struct Node* root;
    Trie() {
        root = new struct Node();
    }
    // 插入操作
    void insert(string word) {
        struct Node* curr = root;
        for(int i=0;i<word.size();i++){
            char c = word[i];
            // 属于字符c的子节点为空,那么插入c
            if(curr->child[c-'a']==NULL){
                curr->child[c-'a'] = new struct Node();
            }
            // 进入下一个节点
            curr = curr->child[c-'a'];
            // 如果当前节点是字符串最后一个,那么将其标记为单词结尾
            if(i==word.size()-1){
                curr->wordend = true;
            }
        }
    }
    // 查找当前单词
    bool search(string word) {
        struct Node* curr = root;
        for(int i=0;i<word.size();i++){
            char c = word[i];
            // 如果当前字符在字典中存在,那么进入下一个节点,如果不存在则返回false
            if(curr->child[c-'a']!=NULL){
                curr = curr->child[c-'a'];
                // 查看当前字符是否是结尾字符
                if(i==word.size()&&curr->wordend ==true){
                    return true;
                }else if(i==word.size()-1&&curr->wordend!=true){
                    return false;
                }
            }else{
                return false;
            }
        }
        return true;
    }
    // 查询前缀的话,则只需要查看是否存在该前缀不需要判断是否是字符的结尾即可
    bool startsWith(string prefix) {
        struct Node* curr = root;
        for(int i=0;i<prefix.size();i++){
            char c = prefix[i];
            if(curr->child[c-'a']!=NULL){
                curr = curr->child[c-'a'];
                if(i==prefix.size()-1){
                    return true;
                }
            }else{
                return false;
            }
        }
        return true;
    }
};

/**
 * 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);
 */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值