Trie树(字典树)

trie树,又称字典树或前缀树,是一种有序 的、用于统计、排序和存储字符串的数据 结构,它与二叉查找树不同,关键字不是 直接保存在节点中,而是由节点在树中的 位置决定。 一个节点的所有子孙都有相同的前缀,也 就是这个节点对应的字符串,而根节点对 应空字符串。一般情况下,不是所有的节点 都有对应的值,只有叶子节点和部分内部节点所对应的键才有相关的值。 trie树的最大优点就是利用字符串的公共前 缀来减少存储空间与查询时间,从而最大 限度地减少无谓的字符串比较,是非常高 效的字符串查找数据结构。

深度遍历

深度搜索trie树,对于正在搜索的节点node: 遍历该节点的26个孩子指针child[i]('a'-'z'),如果指针不空:

将该child[i]对应的字符(i+’a’),push进入栈中, 如果该孩子指针标记的is_end为真(说明这个位置是一个单词):

从栈底到栈顶对栈进行遍历,生成字符串,将它保存到结果数组中 深度搜索child[i]

弹出栈顶字符

Trie树的单词插入

Trie树的单词搜索

#include <iostream>
#include<vector>
#define TRIE_MAX_CHAR_NUM 26
struct TrieNode{
    struct TrieNode * child[TRIE_MAX_CHAR_NUM];
    bool is_end;
    TrieNode() : is_end(false){
        for(int i=0;i< TRIE_MAX_CHAR_NUM;i++){
            child[i] = 0;
        }
    }
};

class TrieTree{
public:
    TrieTree(){
        
    }
    ~TrieTree(){//定义析构函数
        for(int i=0;i<_node_vec.size();i++){
            delete _node_vec[i];
        }
    }
    void insert(const char *word){
        TrieNode *ptr = &_root;
        while(*word){
            int pos = *word - 'a';
            if(!ptr->child[pos]){
                ptr->child[pos] = new_node();
            }
            ptr = ptr->child[pos];
            word++;
        }
        ptr->is_end = true;
    }
    bool startsWith(const char *prefix){
        TrieNode *ptr = &_root;
        while(*prefix){
            int pos = *prefix - 'a';
            if(!ptr->child[pos]){
                return false;
            }
            ptr = ptr->child[pos];
            prefix++;
        }
        return true;
    }
    bool search(const char *word){
        TrieNode *ptr = &_root;
        while(*word){
            int pos = *word - 'a';
            if(!ptr -> child[pos]){
                return false;
            }
            ptr = ptr->child[pos];
            word++;
        }
        return ptr->is_end;
    }
    TrieNode *root(){
        return &_root;
    }
    
private:
    TrieNode *new_node(){
        TrieNode *node = new TrieNode();
        _node_vec.push_back(node);
        return node;
    }
    std::vector<TrieNode *> _node_vec;
    TrieNode _root;
};

void preorder_trie(TrieNode *node,int layer){
    for(int i=0;i<TRIE_MAX_CHAR_NUM;i++){
        if(node->child[i]){
            for(int j=0;j<layer;j++){
                printf("---");
            }
            printf("%c",i+'a');
            if(node->child[i]->is_end){
                printf("(end)");
            }
            printf("\n");
            preorder_trie(node->child[i],layer+1);
        }
    }
}

void get_all_word_from_trie(TrieNode *node,std::string &word,
                            std::vector<std::string> &word_list){
    for(int i=0;i<TRIE_MAX_CHAR_NUM;i++){
        if(node->child[i]){
            word.push_back(i+'a');//将字符入栈
            if(node->child[i]->is_end){
                word_list.push_back(word);
            }
            get_all_word_from_trie(node->child[i],word,word_list);
            word.erase(word.length()-1,1);//弹出栈顶字符
        }
    }
}

int main(int argc, const char * argv[]) {
    TrieTree trie_tree;
    trie_tree.insert("abcd");
    trie_tree.insert("abc");
    trie_tree.insert("abd");
    trie_tree.insert("b");
    trie_tree.insert("bcd");
    trie_tree.insert("efg");
    preorder_trie(trie_tree.root(), 0);
    printf("\n");
    std::vector<std::string> word_list;
    std::string word;
    printf("All words:\n");
    get_all_word_from_trie(trie_tree.root(),word,word_list);
    for(int i=0;i<word_list.size();i++){
        printf("%s\n",word_list[i].c_str());
    }
    printf("\n");
    printf("Search:\n");
    printf("abc:%d\n",trie_tree.search("abc"));
    printf("abcd:%d\n",trie_tree.search("abcd"));
    printf("bc:%d\n",trie_tree.search("bc"));
    printf("b:%d\n",trie_tree.search("b"));
    printf("\n");
    printf("ab:%d\n",trie_tree.startsWith("ab"));
    printf("abc:%d\n",trie_tree.startsWith("abc"));
    printf("bc:%d\n",trie_tree.startsWith("bc"));
    printf("fg:%d\n",trie_tree.startsWith("fg"));
    
    

    return 0;
}

输出:

a
---b
------c(end)
---------d(end)
------d(end)
b(end)
---c
------d(end)
e
---f
------g(end)

All words:
abc
abcd
abd
b
bcd
efg

Search:
abc:1
abcd:1
bc:0
b:1

ab:1
abc:1
bc:1
fg:0
Program ended with exit code: 0

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值