Trie树也称字典树
Trie树
Trie树也称字典树,因为其效率很高,所以在在字符串查找、前缀匹配等中应用很广泛,其高效率是以空间为代价的。
一.Trie树的原理
利用串构建一个字典树,这个字典树保存了串的公共前缀信息,因此可以降低查询操作的复杂度。
下面以英文单词构建的字典树为例,这棵Trie树中每个结点包括26个孩子结点,因为总共有26个英文字母(假设单词都是小写字母组成)。
则可声明包含Trie树的结点信息的结构体:
#define MAX 26 typedef struct TrieNode //Trie结点声明
{
bool isStr; //标记该结点处是否构成单词
struct TrieNode *next[MAX]; //儿子分支
}Trie;
其中next是一个指针数组,存放着指向各个孩子结点的指针。
如给出字符串"abc","ab","bd","dda",根据该字符串序列构建一棵Trie树。则构建的树如下:
Trie树的根结点不包含任何信息,第一个字符串为"abc",第一个字母为'a',因此根结点中数组next下标为'a'-97的值不为NULL,其他同理,构建的Trie树如图所示,红色结点表示在该处可以构成一个单词。很显然,如果要查找单词"abc"是否存在,查找长度则为O(len),len为要查找的字符串的长度。而若采用一般的逐个匹配查找,则查找长度为O(len*n),n为字符串的个数。显然基于Trie树的查找效率要高很多。
但是却是以空间为代价的,比如图中每个结点所占的空间都为(26*4+1)Byte=105Byte,那么这棵Trie树所占的空间则为105*8Byte=840Byte,而普通的逐个查找所占空间只需(3+2+2+3)Byte=10Byte。
二.Trie树的操作
在Trie树中主要有3个操作,插入、查找和删除。一般情况下Trie树中很少存在删除单独某个结点的情况,因此只考虑删除整棵树。
1.插入
假设存在字符串str,Trie树的根结点为root。i=0,p=root。
1)取str[i],判断p->next[str[i]-97]是否为空,若为空,则建立结点temp,并将p->next[str[i]-97]指向temp,然后p指向temp;
若不为空,则p=p->next[str[i]-97];
2)i++,继续取str[i],循环1)中的操作,直到遇到结束符'\0',此时将当前结点p中的isStr置为true。
2.查找
假设要查找的字符串为str,Trie树的根结点为root,i=0,p=root
1)取str[i],判断判断p->next[str[i]-97]是否为空,若为空,则返回false;若不为空,则p=p->next[str[i]-97],继续取字符。
2)重复1)中的操作直到遇到结束符'\0',若当前结点p不为空并且isStr为true,则返回true,否则返回false。
3.删除
删除可以以递归的形式进行删除。
测试程序:
#include <iostream>
using namespace std; #define MAX 26
typedef struct TrieNode
{
bool isStr; //标记该节点处是否构成单词
struct TrieNode *next[MAX];//儿子分支
}Trie; void insert(Trie *root,const char *s)
{
if (root==nullptr||*s=='\0')
{
return;
}
int i;
Trie *p = root;
while (*s!='\0')
{
if (p->next[*s-'a']==nullptr)
{
Trie *temp = (Trie*)malloc(sizeof(Trie));
for (i = ; i < MAX;i++)
{
temp->next[i] = nullptr;
}
temp->isStr = false;
p->next[*s - 'a'] = temp;
p = p->next[*s - 'a'];
}
else
{
p = p->next[*s - 'a'];
}
s++;
}
p->isStr = true;//单词结束的位置标记此处可以构成一个单词
} int search(Trie* root, const char *s)
{
Trie *p = root;
while (p!=nullptr&&*s!='\0')
{
p = p->next[*s-'a'];
s++;
}
return (p!=nullptr&&p->isStr==true);
} void del(Trie *root)
{
for (int i = ; i < MAX;i++)
{
if (root->next[i]!=nullptr)
{
del(root->next[i]);
}
}
free(root);
} int main(int argc, char *argv[])
{
int n, m;//n为建立Trie树输入的单词数;m为要查找的单词数
char s[];
Trie *root = (Trie*)malloc(sizeof(Trie));
for (int i = ; i < MAX;++i)
{
root->next[i] = nullptr;
}
root->isStr = false;
cout << "输入n:\n";
cin >> n;
//getchar();
cout << "输入"<<n<<"个单词:\n";
for (int i = ; i < n;++i)
{
cin >> s;
insert(root, s);
}
while (scanf("%d",&m)!=EOF)
{
cout << "输入m个单词查找,并显示结果:\n";
for (int i = ; i < m;++i)
{
cin >> s;
if (search(root,s)==)
{
cout << "YES\n";
}
else
{
cout << "NO\n";
}
}
}
del(root);
return ;
} //int main()
//{
// char str='a';
// cout << (int)str << endl;
//}
Trie树也称字典树的更多相关文章
- 字典树基础进阶全掌握(Trie树、01字典树、后缀自动机、AC自动机)
字典树 概述 字典树,又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它 ...
- 012-数据结构-树形结构-哈希树[hashtree]、字典树[trietree]、后缀树
一.哈希树概述 1.1..其他树背景 二叉排序树,平衡二叉树,红黑树等二叉排序树.在大数据量时树高很深,我们不断向下找寻值时会比较很多次.二叉排序树自身是有顺序结构的,每个结点除最小结点和最大结点外都 ...
- 字典树&&01字典树专题&&对字典树的理解
对于字典树和01字典树的一点理解: 首先,字典树建树的过程就是按照每个数的前缀来的,如果你要存储一个全小写字母字符串,那么这个树每一个节点最多26个节点,这样的话,如果要找特定的单词的话,按照建树的方 ...
- [LeetCode] Implement Trie (Prefix Tree) 实现字典树(前缀树)
Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inputs ar ...
- POJ 2001 Shortest Prefixes 【 trie树(别名字典树)】
Shortest Prefixes Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 15574 Accepted: 671 ...
- [LeetCode] 208. Implement Trie (Prefix Tree) 实现字典树(前缀树)
Implement a trie with insert, search, and startsWith methods. Example: Trie trie = new Trie(); trie. ...
- 【统计难题】【HDU - 1251】【map打表或字典树】【字典树模板】
思路 题意:题目为中文题,这里不再过多阐述. 思路1:可以在读入单词表的过程中将单词分解,用map将它一 一记录 思路2:利用字典树,这个方法较快些,下面代码中会分别给出数组和结构体指针两种形式的字典 ...
- Trie树-0/1字典树-DFS-1624. 最大距离
2020-03-18 20:45:47 问题描述: 两个二进制串的距离是去掉最长公共前缀的长度之和.比如: 1011000和1011110的最长公共前缀是1011, 距离就是 len("00 ...
- Implement Trie (Prefix Tree)实现字典树
[抄题]: Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inp ...
随机推荐
- Web Server tomcat配置网站
tomcat配置网站 环境变量: 变量名:CATALINA_HOME 变量值:安装路径 1.在tomcat文件夹的conf"catalina"localhost(对于Tomcat6 ...
- .net Windows服务程序和安装程序制作图解 及 VS 2010创建、安装、调试 windows服务(windows service)
.net Windows服务程序和安装程序制作 最近项目中用到window服务程序,以前没接触过,比较陌生,花了两天的时间学习了下,写了个简单的服务,但在制作安装程序的时候,参照网上很多资料,却都制作 ...
- VMware中第一次启动mac遇到的错误及解决方案
本文部分参考 http://blog.sina.com.cn/s/blog_938d86e90100z5ep.html 虚拟机版本:VMware-workstation-full-7.1.3-3242 ...
- Photoshop图层混合模式计算公式大全(转)
混合模式可以将两个图层的色彩值紧密结合在一起,从而创造出大量的效果.在这些效果的背后实际是一些简单的数学公式在起作用.下面我将介绍photoshop cs2中所有混合模式的数学计算公式.另外还介绍了不 ...
- 安装SQL2008的时候 出现System.Configuration.ConfigurationErrorsException: 创建 userSettings/Microsoft.SqlServe
System.Configuration.ConfigurationErrorsException: 创建 userSettings/Microsoft.SqlServer.Configuration ...
- java读取Properties文件
方法一.通过java.util.Properties读取 Properties p=new Properties(); //p需要InputStream对象进行读取文件,而获取InputStream有 ...
- HDU 1231 最大连续子序列
和前面两道题一样 不过这题要求输出子序列首尾的元素的值,而且如果所有元素都小于0的话,规定子序列的和为0,并输出整个序列的首尾元素. //#define LOCAL #include <iost ...
- 51nod1379 索函数
果断打表找规律.然后看得出来是2^k-1之后又不知道怎么求出k有什么卵用... http://blog.csdn.net/guhaiteng/article/details/52094210 %%%% ...
- HDU 3555 Bomb (数位DP-记忆化搜索模板)
题意 求区间[1,n]内含有相邻49的数. 思路 比较简单的按位DP思路.这是第一次学习记忆化搜索式的数位DP,确实比递推形式的更好理解呐,而且也更通用~可以一般化: [数位DP模板总结] int d ...
- 长期演进技术(LTE,Long Term Evolution)
/********************************************************************************* * 长期演进技术(LTE,Long ...