议题: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)的更多相关文章

  1. 笔试算法题(45):简介 - AC自动机(Aho-Corasick Automation)

    议题:AC自动机(Aho-Corasick Automation) 分析: 此算法在1975年产生于贝尔实验室,是著名的多模式匹配算法之一:一个常见的例子就是给定N个单词,给定包含M个字符的文章,要求 ...

  2. 笔试算法题(40):后缀数组 & 后缀树(Suffix Array & Suffix Tree)

    议题:后缀数组(Suffix Array) 分析: 后缀树和后缀数组都是处理字符串的有效工具,前者较为常见,但后者更容易编程实现,空间耗用更少:后缀数组可用于解决最长公共子串问题,多模式匹配问题,最长 ...

  3. 笔试算法题(58):二分查找树性能分析(Binary Search Tree Performance Analysis)

    议题:二分查找树性能分析(Binary Search Tree Performance Analysis) 分析: 二叉搜索树(Binary Search Tree,BST)是一颗典型的二叉树,同时任 ...

  4. hihoCoder #1014 : Trie树 [ Trie ]

    传送门 #1014 : Trie树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互 ...

  5. 前端如何应对笔试算法题?(用node编程)

    用nodeJs写算法题 咱们前端使用算法的地方不多,但是为了校招笔试,不得不针对算法题去练习呀! 好不容易下定决心 攻克算法题.发现js并不能像c语言一样自建输入输出流.只能回去学习c语言了吗?其实不 ...

  6. LeetCode算法题-Lowest Common Ancestor of a Binary Search Tree

    这是悦乐书的第197次更新,第203篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第59题(顺位题号是235).给定二叉搜索树(BST),找到BST中两个给定节点的最低共 ...

  7. 笔试算法题(42):线段树(区间树,Interval Tree)

    议题:线段树(Interval Tree) 分析: 线段树是一种二叉搜索树,将一个大区间划分成单元区间,每个单元区间对应一个叶子节点:内部节点对应部分区间,如对于一个内部节点[a, b]而言,其左子节 ...

  8. 笔试算法题(46):简介 - 二叉堆 & 二项树 & 二项堆 & 斐波那契堆

    二叉堆(Binary Heap) 二叉堆是完全二叉树(或者近似完全二叉树):其满足堆的特性:父节点的值>=(<=)任何一个子节点的键值,并且每个左子树或者右子树都是一 个二叉堆(最小堆或者 ...

  9. 笔试算法题(51):简介 - 红黑树(RedBlack Tree)

    红黑树(Red-Black Tree) 红黑树是一种BST,但是每个节点上增加一个存储位表示该节点的颜色(R或者B):通过对任何一条从root到leaf的路径上节点着色方式的显示,红黑树确保所有路径的 ...

随机推荐

  1. Pow(x, n) 位运算总结 典型

    https://leetcode.com/problems/powx-n/ Implement pow(x, n), which calculates x raised to the power n  ...

  2. P4475 巧克力王国(KDTree)

    传送门 首先可以把约束条件看成一条直线,然后每个巧克力看成一个点,求给定区域内的点权和 用KDTree,每次判断一下当前矩形是否整个都在里面或都在外面,是的话直接返回,否则的话递归 注意,必须该矩形四 ...

  3. [Swift]编程语言:文档修订历史

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  4. vultr 购买vps

    基本安装转自:https://github.com/uxh/shadowsocks_bash/wiki/Vultr%E4%BD%BF%E7%94%A8%E6%95%99%E7%A8%8B 连接 Vul ...

  5. 史上最详细最全的Linux上安装Oracle的教程-centos7

    一.安装Oracle前准备 1.创建运行oracle数据库的系统用户和用户组 [humf@localhost ~]$ su root #切换到root Password: [root@localhos ...

  6. cxf CXF搭建webService服务器

    http://observer.blog.51cto.com/4267416/1231205 手动发布: public class ServerMain { public static void ma ...

  7. Stamps ans Envelope Sive UVA - 242

    ( ||{集合x}表示x中元素1||x中元素2||...||x的最后一个元素||(a,b)表示a||b) ans[i][j][k]表示考虑前i种邮票时取j个邮票能否得到面值kans[i][j][k]= ...

  8. Kruskal HDOJ 4313 Matrix

    题目传送门 题意:如何花最小的代价使得一棵树划分开且不含同类节点 分析:当一条边连接的左右集合同类点小于等于1,那么不用删除,将两个集合合并,要求最小代价,那么贪心思想将权值降序排序,删除后剩下的就是 ...

  9. 2018年全国多校算法寒假训练营练习比赛(第五场):A题:逆序数(树状数组or归并排序)

    题目描述 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数.比如一个序列为4 5 1 3 2, 那么这个序列 ...

  10. MyEclipse去除不必要的validation

    MyEclipse在构建项目时去除不必要的Valication可以加快构建速度. 操作: Window->Perferences->MyEclipse->Validation 在Va ...