数据结构 - Trie树(字典树)
2016-04-11 15:57
671 查看
Trie树
代码实现
无多余空间版本
树的大致结构如下图所示:
从上到下的节点,公共前缀只保存一次。
其实本来实现比较简单,我为了可扩展,所以特意写的复杂了一点。
下面一个是用链表存储内容的,这样节省空间,只是提高了一定程度上的复杂度。
解决了Hihocoder上面的Trie树
代码实现
无多余空间版本
Trie树
也叫单词查找树或者字典树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。树的大致结构如下图所示:
从上到下的节点,公共前缀只保存一次。
代码实现
// // main.cpp // TrieTree // // Created by Alps on 16/4/9. // Copyright © 2016年 chen. All rights reserved. // #include <iostream> #include <cstring> #include <string> using namespace std; #ifndef BranchNum #define BranchNum 26 //记录每个节点的孩子节点最多数量 #endif class Alps_Trie{ public: Alps_Trie(){ root = new TreeNode(); } void addNode(string str){ TreeNode *node = root; for (int i = 0; i < str.length(); i++) { int pos = transToInt(str[i]); if (node->children[pos] == NULL) { node->children[pos] = new TreeNode(); } node = node->children[pos]; } if (node->flag == 0) { node->flag = 1; } } bool searchTree(string str){ TreeNode * node = root; for (int i = 0; i < str.length(); i++) { int pos = transToInt(str[i]); if (node->children[pos] == NULL) { return false; } node = node->children[pos]; } if (node->flag != 0) { return true; } return false; } private: /** * 字典树节点结构 */ struct TreeNode { int flag; //记录单词信息 TreeNode * children[BranchNum]; TreeNode(){ for(int i = 0; i < BranchNum; i++){ children[i] = NULL; } flag = 0; } }; /** * 把每个节点要存储的数据转换成int * * @param ch 字符 * * @return 返回下标 */ int transToInt(char ch){ int temp = ch - 'a'; return temp; } /** * char to string * * @param arr char * * @return string */ string transCharToString(char *arr){ return string(arr); } string transIntToString(int num){ char alps_temp; string alps_str = ""; while (num) { alps_temp = num%10 + '0'; alps_str += alps_temp; num/=10; } return alps_str; } TreeNode * root; }; int main(int argc, const char * argv[]) { Alps_Trie* root = new Alps_Trie(); string str; cout<<"Please input words in dictionary"<<endl; for (int i = 0; i < 3; i++) { cin>>str; root->addNode(str); } cout<<"Please input words you want to search"<<endl; cin>>str; if(root->searchTree(str)){ cout<<"YES"<<endl; }else{ cout<<"NO"<<endl; } return 0; }
其实本来实现比较简单,我为了可扩展,所以特意写的复杂了一点。
无多余空间版本
前面写的是使用数组来定义孩子节点,这样查找速度变为O(1),但是这样有个问题,假如是多叉树,是很容易内存过高的。因为一个节点只有一个孩子,还是要申请最多孩子的空间数量。下面一个是用链表存储内容的,这样节省空间,只是提高了一定程度上的复杂度。
解决了Hihocoder上面的Trie树
#include <iostream> #include <cstring> #include <string> using namespace std; /** * 字典树节点结构 */ struct TreeNode { int flag; //记录单词信息 char ch; TreeNode *left; TreeNode *down; TreeNode(){ flag = 0; left = NULL; down = NULL; } TreeNode(char c){ ch = c; flag = 0; left = NULL; down = NULL; } }; class Alps_Trie{ public: Alps_Trie(){ root = new TreeNode(); } void addNode(string str){ TreeNode *node = root; for (int i = 0; i < str.length(); i++) { if(node->down == NULL){ node->down = new TreeNode(str[i]); node = node->down; node->flag += 1; continue; } TreeNode *next = findChar(node->down, str[i]); if(next == NULL){ next = new TreeNode(str[i]); node = node->down; next ->left = node->left; node->left = next; node = next; node->flag += 1; }else{ node = next; node->flag += 1; } } } int searchTree(string str){ TreeNode * node = root; for (int i = 0; i < str.length(); i++) { TreeNode* next = findChar(node->down, str[i]); if(next == NULL) return 0; node = next; } if (node->flag != 0) { return node->flag; } return 0; } TreeNode * findChar(TreeNode *node, char c){ TreeNode * temp = node; while(temp != NULL){ if(temp->ch == c){ return temp; } temp = temp->left; } return temp; } private: TreeNode * root; }; int main(int argc, const char * argv[]) { Alps_Trie root; string str; int M,N; cin>>M; for (int i = 0; i < M; i++) { cin>>str; root.addNode(str); } cin>>N; for (int i = 0;i < N; i++){ cin>>str; cout<<root.searchTree(str)<<endl; } return 0; } /* 测试数据: 5 babaab babbbaaaa abba aaaaabaa babaababb 5 babb baabaaa bab bb bbabbaab 求得的是公共前缀的字符串数量,上面5个是插入的字符串,下面5个是查找的 */
相关文章推荐
- 微信搜一搜迈出新的一步,好戏来了
- C#数据结构之顺序表(SeqList)实例详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- 数据结构之Treap详解
- 用C语言举例讲解数据结构中的算法复杂度结与顺序表
- C#数据结构之堆栈(Stack)实例详解
- C#数据结构之双向链表(DbLinkList)实例详解
- JavaScript数据结构和算法之图和图算法
- AJAX 支持搜索引擎问题分析
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- 搜索引擎对关键词作弊判断方法揭密
- 使用php记录用户通过搜索引擎进网站的关键词
- android将搜索引擎设置为中国雅虎无法搜索问题解决方法
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture
- java数据结构之java实现栈