数据结构笔记--前缀树的实现

1--前缀树的实现

        前缀树的每一个节点拥有三个成员变量,pass表示有多少个字符串经过该节点,end表示有多少个字符串以该节点结尾,nexts表示该字符串可以走向哪些节点;

#include <iostream>
#include <unordered_map>

struct TreeNode{
    TreeNode() : pass(0), end(0){}
    int pass; // 经过次数
    int end; // 是多少个字符串的结尾
    std::unordered_map<char, TreeNode*> nexts;
};

class Trie{
public:
    // 构造函数
    Trie(){root = new TreeNode();}

    void insert(std::string word){
        if(word.length() == 0) return;
        TreeNode *node = root;
        node->pass++;
        for(int i = 0; i < word.length(); i++){
            if(node->nexts[word[i]] == NULL){ // 哈希表中没有该字符
                node->nexts[word[i]] = new TreeNode(); // 新建该字符
            }
            node = node->nexts[word[i]];
            node->pass++; // 该字符节点经过的次数++
        }
        node->end++; // 遍历word末尾时,节点的end++,表明以该节点结尾的字符串数++
    }

    bool search(std::string word){
        if(word.length() == 0) return true;
        TreeNode *cur = root;
        for(int i = 0; i < word.length(); i++){
            if(cur->nexts[word[i]] == NULL) return 0; // 没有该字符节点
            cur = cur->nexts[word[i]];
        }
        return cur->end; // end不为0表明该字符串出现过
    }

    bool startWith(std::string prefix){
        if(prefix.length() == 0) return 0;
        TreeNode *cur = root;
        for(int i = 0; i < prefix.length(); i++){
            if(cur->nexts[prefix[i]] == NULL) return 0; // 前缀没出现过
            cur = cur->nexts[prefix[i]];
        }
        return cur->pass; // 有多少个字符串经过该前缀,0个表明false;
    }

private:
    TreeNode *root;
};

int main(int argc, char *argv[]){
    Trie T1;
    std::string test1 = "hello";
    T1.insert(test1);
    bool res1 = T1.search(test1);
    if(res1) std::cout << "true" << std::endl;
    else std::cout << "false" << std::endl;

    bool res2 = T1.startWith("hel");
    if(res2) std::cout << "true" << std::endl;
    else std::cout << "false" << std::endl;

    return 0;
}

2--LeetCode真题

2-1--实现Trie(前缀树)

         本题不能自定义节点,因此将 pass、end 和 nexts 等成员变量转换成类的成员变量,新节点就是类的对象;

class Trie{
public:
    // 构造函数
    Trie(){}

    void insert(std::string word){
        if(word.length() == 0) return;
        Trie *node = this;
        node->pass++;
        for(int i = 0; i < word.length(); i++){
            if(node->nexts[word[i]] == NULL){ // 哈希表中没有该字符
                node->nexts[word[i]] = new Trie(); // 新建该字符
            }
            node = node->nexts[word[i]];
            node->pass++; // 该字符节点经过的次数++
        }
        node->end++; // 遍历word末尾时,节点的end++,表明以该节点结尾的字符串数++
    }

    bool search(std::string word){
        if(word.length() == 0) return true;
        Trie *cur = this;
        for(int i = 0; i < word.length(); i++){
            if(cur->nexts[word[i]] == NULL) return 0; // 没有该字符节点
            cur = cur->nexts[word[i]];
        }
        return cur->end; // end不为0表明该字符串出现过
    }

    bool startsWith(std::string prefix){
        if(prefix.length() == 0) return 0;
        Trie *cur = this;
        for(int i = 0; i < prefix.length(); i++){
            if(cur->nexts[prefix[i]] == NULL) return 0; // 前缀没出现过
            cur = cur->nexts[prefix[i]];
        }
        return cur->pass; // 有多少个字符串经过该前缀,0个表明false;
    }

private:
    int pass = 0; // 经过次数
    int end = 0; // 是多少个字符串的结尾
    std::unordered_map<char, Trie*> nexts;
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值