1.Trie导引

Trie树是一种基于树的数据结构,又称单词查找树、前缀树,字典树,是一种哈希树的变种。应用于字符串的统计与排序,经常被搜索引擎系统用于文本词频统计。用于存储字符串以便支持快速模式匹配,主要应用在信息检索中,Trie支持的主要查询操作是模式匹配和前缀匹配。Trie树可以看着是一个确定有限状态自动机,有限状态自动机另一篇博文字符串模式匹配算法——BM、Horspool、Sunday、KMP、KR、AC算法一网打尽 有介绍。

计算机科学中,trie,又称前缀树,是一种有序,用于保存关联数组,其中的键通常是字符串二叉查找树不同,键不是直接保存在节点中,而是由节点在树中的位置决定。一个节点的所有子孙都有相同的前缀,也就是这个节点对应的字符串,而根节点对应空字符串。一般情况下,不是所有的节点都有对应的值,只有叶子节点和部分内部节点所对应的键才有相关的值

Trie 这个术语来自于 retrieval。根据词源学,trie 的发明者 Edward Fredkin 把它读作 /ˈtr/ "tree"。[1][2] 但是,其他作者把它读作 /ˈtr/ "try"。[1][2][3](算法导论也叫做做基数树radix树或retrieval 树)

在图示中,键标注在节点中,值标注在节点之下。每一个完整的英文单词对应一个特定的整数。Trie 可以看作是一个确定有限状态自动机,尽管边上的符号一般是隐含在分支的顺序中的。

键不需要被显式地保存在节点中。图示中标注出完整的单词,只是为了演示 trie 的原理。

trie 中的键通常是字符串,但也可以是其它的结构。trie 的算法可以很容易地修改为处理其它结构的有序序列,比如一串数字或者形状的排列。比如,bitwise trie 中的键是一串位元,可以用于表示整数或者内存地址。

2.标准Trie

令S是取自字母表∑的s个集合,满足S中不存在一个串是另一个串的前缀。S的一个标准Trie(standard trie)是一颗有序书T,满足如下性质:

  • 除了根之外,T中的每个结点标记有∑的一个字符。
  • T中一个内部结点的子结点的次序有字母表∑上的规范次序确定。
  • T有s个外部结点(叶结点),每个外部结点关联S中的一个串,满足从根到T中一个外部结点v的路径上标记连接产生S中关联的一个串。

下图是串{bear,bell,bid,bull,buy,sell,stock,stop}的标准Trie

#include<algorithm>
#include<iostream>
using namespace std; const int sonnum=,base='a';
struct Trie
{
int num;//to remember how many word can reach here,that is to say,prefix
bool terminal;//If terminal==true ,the current point has no following point
struct Trie *son[sonnum];//the following point
};
Trie *NewTrie()// create a new node
{
Trie *temp=new Trie;
temp->num=;temp->terminal=false;
for(int i=;i<sonnum;++i)temp->son[i]=NULL;
return temp;
}
void Insert(Trie *pnt,char *s,int len)// insert a new word to Trie tree
{
Trie *temp=pnt;
for(int i=;i<len;++i)
{
if(temp->son[s[i]-base]==NULL)
temp->son[s[i]-base]=NewTrie();
else
temp->son[s[i]-base]->num++; temp=temp->son[s[i]-base];
}
temp->terminal=true; } void Delete(Trie *pnt)// delete the whole tree
{
if(pnt!=NULL)
{
for(int i=;i<sonnum;++i)if(pnt->son[i]!=NULL)Delete(pnt->son[i]);
delete pnt;
pnt=NULL;
}
}
Trie* Find(Trie *pnt,char *s,int len)//trie to find the current word
{
Trie *temp=pnt;
for(int i=;i<len;++i)
{
if(temp->son[s[i]-base]!=NULL)
{
cout<<temp->son[s[i]-base]->num<<ends<<s[i]<<endl;//没有打印根节点的num
temp=temp->son[s[i]-base];
}
else return NULL;
}
return temp;
} int main()
{
Trie *root;
root=NewTrie();
Insert(root,"bear",);
Insert(root,"bell",);
Insert(root,"bid",);
Insert(root,"bull",);
Insert(root,"buy",); Trie *res;
res=Find(root,"bear",);
if(res!=NULL)
{
cout<<res->terminal;
}
else
cout<<"not found";
}

输出:

5 b

2 3

1 a

1 r

1 找到了。(代码参考:http://hi.baidu.com/luyade1987/item/7c1977f5e9015cdf6225d224)

存储总长为n,来自大小为d的字母表中s个串的集合S的标准Trie具有如下性质:

  1. T中每个内部结点最多有d个子结点。
  2. T有s个外部结点。(显然,有s个串)
  3. T的高度等于最长串的长度。
  4. T中的结点书为O(n)。

性能:对于有n个英文字母的串来说,在内部结点中定位指针所需要花费O(d)时间,d为字母表的大小,英文为26。由于在上面的算法中内部结点指针定位使用了数组随机存储方式,因此时间复杂度降为了O(1)。但是如果是中文字,下面在实际应用中会提到。因此我们在这里还是用O(d)。 查找成功的时候恰好走了一条从根结点到叶子结点的路径。因此时间复杂度为O(d*n)。但是,当查找集合X中所有字符串两两都不共享前缀时,trie中出现最坏情况。除根之外,所有内部结点都自由一个子结点。此时的查找时间复杂度蜕化为O(d*(n^2))

Trie树的特点如下:
1)根节点不包含字符,除根节点外每一个节点都只包含一个字符。
2)从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
3)每个节点的所有子节点包含的字符都不相同。(也就是孩子都不相同)
 
http://dsqiu.iteye.com/blog/1705697

http://en.wikipedia.org/wiki/Trie

http://blog.csdn.net/v_july_v/article/details/6897097

Trie三兄弟——标准Trie、压缩Trie、后缀Trie的更多相关文章

  1. 标准Trie、压缩Trie、后缀Trie

    ref : https://dsqiu.iteye.com/blog/1705697 1.Trie导引 Trie树是一种基于树的数据结构,又称单词查找树.前缀树,是一种哈希树的变种.应用于字符串的统计 ...

  2. 站长管理服务器必读:Ftp、Ftps与Sftp三兄弟的不同与区别以及部署全指引

    文章标题: 站长管理服务器必读:Ftp.Ftps与Sftp三兄弟的不同与区别以及部署全指引 关键字 : ftp,sftp,freesshd,ftps 文章分类: 教程 创建时间: 2020年3月23日 ...

  3. Nancy之Pipelines三兄弟(Before After OnError)

    一.简单描述 Before:如果返回null,拦截器将主动权转给路由:如果返回Response对象,则路由不起作用. After : 没有返回值,可以在这里修改或替换当前的Response. OnEr ...

  4. 好用的排名函数~ROW_NUMBER(),RANK(),DENSE_RANK() 三兄弟

    排名函数三兄弟,一看名字就知道,都是为了排名而生!但是各自有各自的特色!以下一个例子说明问题!(以下栗子没有使用Partition By 的关键字,整个结果集进行排序) RANK 每个值一个排名,同样 ...

  5. sql语句中----删除表数据的"三兄弟"

    说到删除表数据的关键字,大家记得最多的可能就是delete了 然而我们做数据库开发,读取数据库数据.对另外的两兄弟用得就比较少了 现在来介绍另外两个兄弟,都是删除表数据的,其实也是很容易理解的 老大- ...

  6. 由fprintf和printf看C语言三种标准流

    一.C语言中的三种标准流 1.标准输入流:stdin 2.标准输出流:stdout 3.标准错误输出流:stderr 他们的类型都是File * 二.fprintf于printf的区别 frintf( ...

  7. Oracle数据库三种标准的备份方法

    Oracle数据库的三种标准的备份方法: 1.导出/导入(EXP/IMP). 2.热备份. 3.冷备份. 注释:导出备件是一种逻辑备份,冷备份和热备份是物理备份. 一.导出/导入(Export/Imp ...

  8. Promise的三兄弟:all(), race()以及allSettled()

    摘要: 玩转Promise. 原文:Promise 中的三兄弟 .all(), .race(), .allSettled() 译者:前端小智 Fundebug经授权转载,版权归原作者所有. 从ES6 ...

  9. 一网打尽 @ExceptionHandler、HandlerExceptionResolver、@controlleradvice 三兄弟!

    把 @ExceptionHandler.HandlerExceptionResolver.@controlleradvice 三兄弟放在一起来写更有比较性.这三个东西都是用来处理异常的,但是它们使用的 ...

随机推荐

  1. 根据输出设置select的被选中值

    $("#startupStatus").find("option").map(function(i) { if ($('#st-status').val() = ...

  2. Android布局绘制常见小问题

    一些网上分享的整理 1.Android设置Selector不同状态下颜色及图片 Selector常用状态: android:state_selected 控件选中状态,可以为true或false an ...

  3. pycharm中添加扩展工具pylint

    今天调试了好几个小时,想吧pylint集成到pycharm中去,从网上找了个宝贝帖 子,但是不好用,原因是作者写的脚本是检查工程和模块的,而我的是单独检查一个文件,当然前者肯定会在项目后期用的.所以就 ...

  4. 微型 ORM 的第二篇 DapperLambda性能测试[Dapper比较篇]

    由于这周比较忙,所以本来想做的性能测试,一直没时间,想想还是今天给补上吧 由于很多人都担心性能问题,封装之后跟Dapper的性能差距是多少,今天我给出我的测试方法,仅供参考. 创建IDbConnect ...

  5. 155Min Stack

    题目地址:155Min Stack 最近为了提高数据结构和算法能力,保证每天一到leetcode的题目.从easy开始,感觉这道题目还蛮好,记录一下. 题目大意:就是维护一个栈,获得栈中元素的的最小值 ...

  6. Oracle学习之常见问题处理

    转自:http://blog.csdn.net/liusong0605/article/details/16349121 安装完oracle并启动服务后,通过sqlPlus无法登录,出现如下错误: s ...

  7. java.el.PropertyNotFoundException解决方法

    今天在开发中遇到了java.el.PropertyNotFoundException异常,检查JSP页面.Action.Bean.都没有发现错误 在网上搜了一下可能是我的bean不是一个标准的bean ...

  8. ObjectiveC 文件操作二

    10,文件委托,以便操作文件.头部看起来像是这样. @interface MyFileManager : NSObject @property(strong)NSFileManager *fileMa ...

  9. Making your first driver - complete walkthrough(使用VisualDDK)

    This article describes how to create, build and debug your first driver using Visual Studio and Visu ...

  10. iPhone 6 为何坚持1GB内存?

    原文地址:http://digi.ifeng.com/expert/special/96/#6467378-qzone-1-9015-46cf52f061fd6e814686a918cedcb024 ...