赞
踩
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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。