Trie树的创建、插入、查询的实现
原文:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=28977986&id=3807947
1、什么是Trie树
Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。
Trie的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。
它有3个基本性质:
1.根节点不包含字符,除根节点外每一个节点都只包含一个字符。
2.从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
3.每个节点的所有子节点包含的字符都不相同。
本质上,Trie是一颗存储多个字符串的树。相邻节点间的边代表一个字符,这样树的每条分支代表一则子串,而树的叶节点则代表完整的字符串。和普通树不同的地方是,相同的字符串前缀共享同一条分支。举一个例子。给出一组单词,inn, int, at, age, adv, ant, 我们可以得到下面的Trie:

搭建Trie的基本算法很简单,无非是逐一把每则单词的每个字母插入Trie。插入前先看前缀是否存在。如果存在,就共享,否则创建对应的节点和边。比如要插入单词add,就有下面几步:
1.考察前缀"a",发现边a已经存在。于是顺着边a走到节点a。
2.考察剩下的字符串"dd"的前缀"d",发现从节点a出发,已经有边d存在。于是顺着边d走到节点ad
3.考察最后一个字符"d",这下从节点ad出发没有边d了,于是创建节点ad的子节点add,并把边ad->add标记为d。
具体Trie树的创建、插入、查询代码如下所示:
//此函数只考虑26个英文字母的情况
#include<iostream>
#include<cstring>
using namespace std; #define MAX_CHILD 26 typedef struct Tree
{
int count; //用来标记该节点是个可以形成一个单词,如果count!=0,则从根节点到该节点的路径可以形成一个单词
struct Tree *child[MAX_CHILD];
}Node,*Trie_node; Node* CreateTrie() //创建trie节点树
{
Node *node=(Node*)malloc(sizeof(Node));
memset(node,,sizeof(Node));
return node;
} void insert_node(Trie_node root,char *str) //trie树插入结点
{
if(root ==NULL || *str=='\0')
return;
Node *t=root; char *p=str; while(*p!='\0')
{
if(t->child[*p-'a']==NULL)
{
Node *tmp=CreateTrie();
t->child[*p-'a']=tmp;
}
t=t->child[*p-'a'];
p++;
}
t->count++;
} void search_str(Trie_node root,char *str) //查找串是否在该trie树中
{
if(NULL==root || *str=='\0')
{
printf("trie is empty or str is null\n");
return;
} char *p=str;
Node *t=root;
while(*p!='\0')
{
if(t->child[*p-'a']!=NULL)
{
t=t->child[*p-'a'];
p++;
}
else
break;
}
if(*p=='\0')
{
if(t->count==)
cout<<"该字符串不在trie树中,但该串是某个单词的前缀\n";
else
cout<<"该字符串在该trie树中\n";
}
else
cout<<"该字符串不在trie树中\n";
} void del(Trie_node root) //释放整个字典树占的堆空间
{
int i;
for(i=;i<MAX_CHILD;i++)
{
if(root->child[i]!=NULL)
del(root->child[i]);
}
free(root);
} int main()
{
int i,n;
char str[];
cout<<"请输入要创建的trie树的大小:";
cin>>n;
Trie_node root=NULL;
root=CreateTrie();
if(root==NULL)
cout<<"创建trie树失败";
for(i=;i<n;i++)
{
scanf("%s",str);
insert_node(root,str);
}
cout<<"trie树已建立完成\n";
cout<<"请输入要查询的字符串:";
while(scanf("%s",str)!=NULL)
{
search_str(root,str); }
return ; }
Trie树的创建、插入、查询的实现的更多相关文章
- Trie树的应用:查询IP地址的ISP
1. 问题描述 给定一个IP地址,如何查询其所属的ISP,如:中国移动(ChinaMobile),中国电信(ChinaTelecom),中国铁通(ChinaTietong)?现有ISP的IP地址区段可 ...
- 字典树(Trie树)的实现及应用
>>字典树的概念 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树.与二叉查找树不同,Trie树的 ...
- [转] Trie树详解及其应用
一.知识简介 最近在看字符串算法了,其中字典树.AC自动机和后缀树的应用是最广泛的了,下面将会重点介绍下这几个算法的应用. 字典树(Trie)可以保存一些字符串->值 ...
- Trie树详解及其应用
一.知识简介 最近在看字符串算法了,其中字典树.AC自动机和后缀树的应用是最广泛的了,下面将会重点介绍下这几个算法的应用. 字典树(Trie)可以保存一些字符串->值的对 ...
- POJ 3630 Phone List(trie树的简单应用)
题目链接:http://poj.org/problem?id=3630 题意:给你多个字符串,如果其中任意两个字符串满足一个是另一个的前缀,那么输出NO,否则输出YES 思路:简单的trie树应用,插 ...
- trie树---(插入、删除、查询字符串)
HDU 5687 Problem Description 度熊手上有一本神奇的字典,你可以在它里面做如下三个操作: 1.insert : 往神奇字典中插入一个单词 2.delete: 在神奇字 ...
- Trie树-提高海量数据的模糊查询性能
今天这篇文章源于上周在工作中解决的一个实际问题,它是个比较普遍的问题,无论做什么开发,估计都有遇到过.具体是这样的,我们有一份高校的名单(2657个),需要从海量的文章标题中找到包含这些高校的标题,其 ...
- python Trie树和双数组TRIE树的实现. 拥有3个功能:插入,删除,给前缀智能找到所有能匹配的单词
#coding=utf- #字典嵌套牛逼,别人写的,这样每一层非常多的东西,搜索就快了,树高26.所以整体搜索一个不关多大的单词表 #还是O(). ''' Python 字典 setdefault() ...
- 线段树&&线段树的创建线段树的查询&&单节点更新&&区间更新
目录 线段树 什么是线段树? 线段树的创建 线段树的查询 单节点更新 区间更新 未完待续 线段树 实现问题:常用于求数组区间最小值 时间复杂度:(1).建树复杂度:nlogn.(2).线段树算法复杂度 ...
随机推荐
- JetBrains激活
https://www.imsxm.com/jetbrains-license-server/ 已经累计为大家激活1360577次 :) JetBrains授权服务器:http://idea.imsx ...
- spark配置lzo
spark1.0版本 spark-env.sh中 export SPARK_LIBRARY_PATH=$SPARK_LIBRARY_PATH:/soft/hadoop/lzo/lib/export S ...
- poj1050
To the Max Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 39081 Accepted: 20639 Desc ...
- 第四章ContentProvider
No resource found that matches the given name 'Theme.AppCompat.Light'.
- 多层数据库应用基于Delphi DataSnap方法调用的实现(一)返回数据集
从Delphi 2009开始,DataSnap技术发生了很大的变化,并在Delphi 2010和Delphi XE的后续版本中得到了持续的改进.Delphi 2009之前的DataSnap,虽然也实现 ...
- Xrm.Utility.openEntityForm 时404.15 maxQueryString 错误 和 长度超过maxQueryStringLength值 错误
最近的项目里用到Xrm.Utility.openEntityForm 创建新记录时分别碰到以下错误: 以及 这两个错误都是因为想传递给表单的参数太多导致的url 查询参数太长导致的,前者是因为iis的 ...
- 运行Java cmd程序 找不到或无法加载主类怎么解决
//这个问题原因有以下几种,但是和环境变量并没有太大的关系 //能够执行java 和 javac 就证明你的环境变量已经配置好了,其实 classpath 可以不配置 //假如有如下文件:H:\cod ...
- 清空表数据 mysql让主键从1开始
TRUNCATE TABLE name 删除表中的所有行,而不记录单个行删除操作.
- scala数组
#scala数组 val A= new Array[T](N) val A = new Array[Int](10) ##变长数组 import scala.collection.mutable.Ar ...
- Spring JDBC
转载:博客主页:http://blog.csdn.NET/chszs 一.概述 在Spring JDBC模块中,所有的类可以被分到四个单独的包:1)core即核心包,它包含了JDBC的核心功能.此包内 ...