笔试算法题(39):Trie树(Trie Tree or Prefix Tree)
议题:TRIE树 (Trie Tree or Prefix Tree);
分析:
又称字典树或者前缀树,一种用于快速检索的多叉树结构;英文字母的Trie树为26叉树,数字的Trie树为10叉树;All the descendants of a node have a common prefix of the sequence associated with that node, and the root is associated with the empty sequence. 由于不同的sequence使用公共的前缀,所以Trie树可以节省大量空间;但如果sequence仅有很少的公共前缀时,Trie树耗用较大的空间;
Trie树中根节点为空字符,其他每个节点仅包含一个字符;从根节点到某一个终止节点的路径上经过的字符连接起来就是对应的string;Trie树中查 找长度为M的string的时间复杂度为O(M),BST树中查找长度为M的string则需要O(MlogN),N为树中的节点数,则logN为树的高 度,并且前提是BST为平衡树,Trie树的时间复杂度不受树是否平衡的影响;对于Hash表而言,其也可以实现查找,但是Trie树可以实现 Closest Fit,也就是近似查找,Hash表不能实现近似查找;同时,Hash表有插入冲突需要解决;
Trie树中有两类节点,元素节点和分支节点,前者表示一条完整路径的终结,后者表示路径中的一个节点;Trie树的应用包括字典查找 (Dictionary String Search)和近似匹配算法(Approximate Matching Algorithm);Trie树有三种结构:Standard Trie,Compressed Trie和Suffix Trie;标准Trie其实就是Prefix Trie;由于string本身可以存在一个单独的string1是另一个单独的string2的前缀,但是Trie树中规定所有stirng都是从根节 点到叶子节点的完整路径,所以实际实现中需要在所有string最后引入一个$字符标志结束;
由于使用树+指针实现Trie树非常耗用内存,所以首先可以将原始Trie树进行压缩,也就是只有单个子节点的节点可以合并成一个节点;同时可以使用Double-Array Trie作为Trie树的实现:
样例:
#define MAX_NUM 26
/**
* 表示两种类型的节点
* */
enum NodeType {
COMPLETED,
UNCOMPLETED
};
/**
* child指针数组存储a-z字母对应的索引
* */
struct Node {
NodeType type;
char ch;
Node *child[MAX_NUM];
}; Node *root; Node* CreateNode(char ch) {
Node *node=new Node();
node->ch=ch;
node->type=UNCOMPLETED;
for(int i=;i<MAX_NUM;i++)
node->child[i]=NULL;
return node;
}
/**
* 初始化:将根节点创建为空字符的节点
* */
void Init() {
root=CreateNode('');
} void Clean(Node *root) {
if(root==NULL) return;
for(int i=;i<MAX_NUM;i++) {
/**
* 首先递归处理子节点
* */
Clean(root->child[i]);
}
/**
* 删除动态内存
* */
delete [] root->child;
/**
* 删除节点本身
* */
delete root;
} bool IsExisted(char *string,int length) {
Node *index=root;
Node *temp;
int i;
for(i=;i<length;i++) {
temp=index->child[string[i]-'a'];
/**
* 如果某一个字符对应的指针位置为NULL,说明
* 此字符不存在
* */
if(temp==NULL)
break;
index=index->child[string[i]='a'];
}
/**
* 仅当string匹配完全,并且trie树正好到达结束节点
* 才成功返回
* */
if((i==length) && (index->type==COMPLETED))
return true;
else
return false;
} void InsertNew(char *string, int length) {
Node *index=root;
Node *temp;
int i;
for(i=;i<length;i++) {
temp=index->child[string[i]-'a'];
if(temp==NULL)
/**
* 新插入的string的每一个字符都创建一个节点
* */
temp=CreateNode(string[i]);
index=index->child[string[i]-'a'];
}
/**
* 最后一个节点需要为结束节点
* */
index->type=COMPLETED;
}
参考连接:
http://linux.thai.net/~thep/datrie/datrie.html
http://hxraid.iteye.com/blog/618962
笔试算法题(39):Trie树(Trie Tree or Prefix Tree)的更多相关文章
- 笔试算法题(45):简介 - AC自动机(Aho-Corasick Automation)
议题:AC自动机(Aho-Corasick Automation) 分析: 此算法在1975年产生于贝尔实验室,是著名的多模式匹配算法之一:一个常见的例子就是给定N个单词,给定包含M个字符的文章,要求 ...
- 笔试算法题(40):后缀数组 & 后缀树(Suffix Array & Suffix Tree)
议题:后缀数组(Suffix Array) 分析: 后缀树和后缀数组都是处理字符串的有效工具,前者较为常见,但后者更容易编程实现,空间耗用更少:后缀数组可用于解决最长公共子串问题,多模式匹配问题,最长 ...
- 笔试算法题(58):二分查找树性能分析(Binary Search Tree Performance Analysis)
议题:二分查找树性能分析(Binary Search Tree Performance Analysis) 分析: 二叉搜索树(Binary Search Tree,BST)是一颗典型的二叉树,同时任 ...
- hihoCoder #1014 : Trie树 [ Trie ]
传送门 #1014 : Trie树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互 ...
- 前端如何应对笔试算法题?(用node编程)
用nodeJs写算法题 咱们前端使用算法的地方不多,但是为了校招笔试,不得不针对算法题去练习呀! 好不容易下定决心 攻克算法题.发现js并不能像c语言一样自建输入输出流.只能回去学习c语言了吗?其实不 ...
- LeetCode算法题-Lowest Common Ancestor of a Binary Search Tree
这是悦乐书的第197次更新,第203篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第59题(顺位题号是235).给定二叉搜索树(BST),找到BST中两个给定节点的最低共 ...
- 笔试算法题(42):线段树(区间树,Interval Tree)
议题:线段树(Interval Tree) 分析: 线段树是一种二叉搜索树,将一个大区间划分成单元区间,每个单元区间对应一个叶子节点:内部节点对应部分区间,如对于一个内部节点[a, b]而言,其左子节 ...
- 笔试算法题(46):简介 - 二叉堆 & 二项树 & 二项堆 & 斐波那契堆
二叉堆(Binary Heap) 二叉堆是完全二叉树(或者近似完全二叉树):其满足堆的特性:父节点的值>=(<=)任何一个子节点的键值,并且每个左子树或者右子树都是一 个二叉堆(最小堆或者 ...
- 笔试算法题(51):简介 - 红黑树(RedBlack Tree)
红黑树(Red-Black Tree) 红黑树是一种BST,但是每个节点上增加一个存储位表示该节点的颜色(R或者B):通过对任何一条从root到leaf的路径上节点着色方式的显示,红黑树确保所有路径的 ...
随机推荐
- 461. Hamming Distance(汉明距离)
The Hamming distance between two integers is the number of positions at which the corresponding bits ...
- HDU 4893 Wow! Such Sequence! (树状数组)
题意:给有三种操作,一种是 1 k d,把第 k 个数加d,第二种是2 l r,查询区间 l, r的和,第三种是 3 l r,把区间 l,r 的所有数都变成离它最近的Fib数, 并且是最小的那个. 析 ...
- bzoj 2438: [中山市选2011]杀人游戏【tarjan】
没看太懂题意orz 最优的是tarjan缩点之后问入度为0的点,因为问这个点可以知道整个块的情况 答案是这ans个入度为0的点都不是杀手的概率\( \frac{n-ans}{n} \) 但是有特殊情况 ...
- bzoj 3612: [Heoi2014]平衡【整数划分dp】
其实就是-n~n中求选k个不同的数,和为0的方案数 学到了新姿势叫整数划分,具体实现是dp 详见:https://blog.csdn.net/Vmurder/article/details/42551 ...
- 洛谷 P3959 宝藏【状压dp】
一开始状态设计错了-- 设f[i][s]为当前与根节点联通状况为s,最深深度为i 转移的话枚举当前没有和根联通的点集,预处理出把这些点加进联通块的代价(枚举s中的点和当前点的连边乘以i即可),然后用没 ...
- 洛谷 P1251 餐巾计划问题【最小费用最大流】
建图细节比较多,对于每个点i,拆成i和i',i表示用的餐巾,i'表示脏餐巾,连接: (s,i,r[i],p)表示在这一天买新餐巾 (i,t,r[i],0)表示这一天用了r[i]的餐巾 (s,i+n,r ...
- 洛谷P3246 [HNOI2016]序列
传送门 题解 //minamoto #include<iostream> #include<cstdio> #define ll long long using namespa ...
- unsign 字段相减出现负数解决方法
在项目中做数据统计的时候需要用到几个字段相减得到想要的值,但是因为字段都是无符号,相减出现mysql 错误 BINGINT UNSIGNED VALUE .. 在c语言中两个无符号相减值为负数,该值 ...
- 【笔记】对自定义异常的理解(Java)
原本,原有的异常是非手动地.自动地抛出的. 了解自定义异常时,发现其信息只是: 继承了谁,即它自己算哪种异常: 它的信息,比如一个ID,这个貌似还是可选的: 它是可被传入信息的 没有遗漏的话,就这仨了 ...
- ACM_跳坑小能手(暴力)
跳坑小能手 Time Limit: 2000/1000ms (Java/Others) Problem Description: GDUFE-GAME现场有一个游戏场地人头窜动,围观参与游戏的学生在场 ...