了解这个数据结构之前我们需要了解它能被用来做什么

字典树又称单词查找树,Tire树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。

说到底,字典树就是用来查询公共前缀的一个工具,延伸的话可以用来进行串匹配,词频统计等,也是学AC自动机的前置技能.

所谓的字典树,其实就是一个n叉树


我们对于每个字母,如果有公共前缀的,我们找到它的前缀,在后面不同的部分建立不同的子节点,比如说apple,appear,appxy 三个不同的单词,公共前缀为app,所以建树如下:

如果下面有一个单词为apzl的话,建树如下

也就是只注意前缀相同的部分,后面即使有一样的字母也重新建立子节点


那么问题来了,单词的第一个字母不止A啊,应该怎么办?
其实不难,学过二分图的应该能想出来:设置一个超级源点,我们在第一个字母上面再设一个超级源点,这样计算的时候不考虑他就行了,这样第一层就可以和下面的子节点一样建立了
如图所示(ps:此图有误,apply应该为appxy)


又是喜(sang)闻(xin)乐(bing)见(kuang)的代码环节了
个人由于ACM的原因,就只放数组实现的板子了,(反正懂原理了指针版的也挺简单的)

由于数组不能动态开内存,所以我们就得采用模拟的形式了,这里其实用了一点并查集的思想,各位客官看下图

由于不能动态分配内存,同时字典树又是比较耗费空间的,所以我们的内存分配尽可能大,开一个二维数组tire[maxn][26],然后tire[i][j] = k 代表编号为i的节点的第j个孩子是编号为k的节点,这里的j通常指当前位的字母A-Z然后关于编号,我们这里的存树方式是:如果要生成新节点,则编号++,否则编号不动,所以如上图,APPLY的对应编号应该为1,2,3,4,10,11;
同时有:

tire[1]['A'-'A'] = 2;
tire[2]['P'-'A'] = 3;
tire[3]['P'-'A']  = 10;
tire[10]['X'-'A'] = 11;
tire[11]['Y'-'A'] = 0;

这样,查找的时候利用并查集的思想不断向下查找即可

代码如下

/*头文件可以忽略,只是一些常用的宏*/
#include <map>
#include <queue>
#include <cstdlib>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <fstream>
#include <iostream>
#include <sstream>
#include <algorithm>
#define _mem(a,b) memset(a,0,(b+3)<<2)
#define fori(a) for(int i=0;i<a;i++)
#define forj(a) for(int j=0;j<a;j++)
#define ifor(a) for(int i=1;i<=a;i++)
#define jfor(a) for(int j=1;j<=a;j++)
#define mem(a,b) memset(a,b,sizeof(a))
#define IN freopen("in.txt","r",stdin)
#define OUT freopen("out.txt","w",stdout)
#define IO do{\ios::sync_with_stdio(false);\cin.tie(0);\cout.tie(0);}while(0)
#define mp(a,b) make_pair(a,b);
using namespace std;
typedef long long ll;
const int maxn =  1e5;
const int INF = 0x3f3f3f3f;
const int inf = 0x3f;
const double EPS = 1e-7;
const double Pi = acos(-1);
const int MOD = 1e9+7;
int Tire[maxn][26];
char str[2000005];
bool v[maxn];
string s;
int cnt = 1;
//建树,每输入一个单词到s里面就调用_insert()就好
void _insert(){int root = 0;fori(s.size()){int next = s[i] - 'A';if(!Tire[root][next])Tire[root][next] = ++cnt;root = Tire[root][next];}v[root] = true;//这里用了一个标记数组表示该点存在一个完整的单词,比如说`app`和`apple`//在最后一个`p`的位置就会被标记true
}//查找最长公共前缀
int _find(char bufs[],int leng){int root = 0;int cns = 0;int next;int res = 0;fori(leng){next = bufs[i] - 'A';if(Tire[root][next] == 0)break;root = Tire[root][next];cns++;if(v[root])res = cns;}return res;
}

转载于:https://www.cnblogs.com/bestsort/p/10588835.html

Tre树(字典树)数据结构详解(图解)及模板相关推荐

  1. 树状数组 数据结构详解与模板(可能是最详细的了)

    目录 转载请注明出处:bestsort.cn 树状数组基础 单点更新: 区间查询: 高级操作 求逆序对 操作 原理 求区间最大值 区间修改+单点查询 查询 修改 区间修改+区间查询 查询 修改 二维树 ...

  2. AC自动机 算法详解(图解)及模板

    要学AC自动机需要自备两个前置技能:KMP和trie树(其实个人感觉不会kmp也行,失配指针的概念并不难) 其中,KMP是用于一对一的字符串匹配,而trie虽然能用于多模式匹配,但是每次匹配失败都需要 ...

  3. 数据结构详解——最大(小)左倾树

    数据结构详解--最大(小)左倾树 文章目录 数据结构详解--最大(小)左倾树 最大(小)左倾树的定义及用途 操作最大HBLT 合并操作 插入操作和删除操作 初始化操作 Java语言实现的最大HBLT ...

  4. 数据结构图文解析之:哈夫曼树与哈夫曼编码详解及C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  5. [redis] 10 种数据结构详解

    [redis] 10 种数据结构详解 简介 5种常见数据结构 string: 最常见的 string key value list: 双向链表 set: 集合- zset: 有序集合 hash: 类似 ...

  6. 万字长文的Redis五种数据结构详解(理论+实战),建议收藏。

    本文脑图 前言 Redis是基于c语言编写的开源非关系型内存数据库,可以用作数据库.缓存.消息中间件,这么优秀的东西一定要一点一点的吃透它. 关于Redis的文章之前也写过三篇,阅读量和读者的反映都还 ...

  7. Python中的高级数据结构详解

    这篇文章主要介绍了Python中的高级数据结构详解,本文讲解了Collection.Array.Heapq.Bisect.Weakref.Copy以及Pprint这些数据结构的用法,需要的朋友可以参考 ...

  8. 探索Redis设计与实现6:Redis内部数据结构详解——skiplist

    Redis内部数据结构详解(6)--skiplist  2016-10-05 本文是<Redis内部数据结构详解>系列的第六篇.在本文中,我们围绕一个Redis的内部数据结构--skipl ...

  9. python字典之defaultdict详解

    python字典之defaultdict详解 defaultdict为你的字典设定一个默认值或者默认值的数据类型: defaultdict接受一个工厂函数作为参数,如下来构造: dict =defau ...

  10. redis数据结构详解之Hash(四)

    原文:redis数据结构详解之Hash(四) 序言 Hash数据结构累似c#中的dictionary,大家对数组应该比较了解,数组是通过索引快速定位到指定元素的,无论是访问数组的第一个元素还是最后一个 ...

最新文章

  1. 没错,老板让我写个 BUG!
  2. Knative 入门系列1:knative 概述
  3. POJ1185:火炮(减少国家)
  4. 无线基站侧的信令风暴根因——频繁的释放和连接RRC产生大量信令、设备移动导致小区重选信令增加、寻呼信令多...
  5. 国家发改委:春运期间推动“健康码”全国一码通行
  6. 正确使用 SharePoint 对象避免内存泄漏(续)
  7. elemet UI 中表格数据的排序操作
  8. 未找到导入的项目,请确认 Import 声明中的路径正确
  9. centos7 下安装Poco
  10. Markdown编辑器
  11. QQ浏览器,正式推出,9.0版本又多些好东西!
  12. opmanager监控linux,OpManager管理员指南.doc
  13. Git学习笔记--廖雪峰官网教程
  14. linux ftp命令下载目录,linux命令行下的ftp 多文件下载和目录下载
  15. 微信 语音识别_微信语音识别_微信语音识别api - 云+社区 - 腾讯云
  16. 使用 DiskMaker X 轻松制作 Yosemite 安装 U 盘(引)
  17. 如何更换计算机cpu风扇,cpu风扇怎么拆下来 cpu风扇正确拆卸方法图解
  18. Acwing-872. 最大公约数
  19. 禅道发信配置(网易企业邮箱)
  20. Android Jason数据解析及显示

热门文章

  1. springBoot实现http代理ip
  2. 广东汤谱大全 广东煲汤食谱大全
  3. com命令显示到服务器链路,必须收藏的linux shell常用命令
  4. LaTeX 中的段落和换行
  5. python做出来的小程序、可以在win10上面运行_超详细,手把手教你用20行Python代码制作飞花令小程序!...
  6. 红外弱小目标检测:MPCM算法解读及MATLAB复现
  7. HIT-计算机系统大作业2022-程序人生-Hello‘s P2P
  8. JS实现小球移动(点击移动,点击停止)
  9. android jpush 极光推送
  10. 怎么把人脸检测的速度做到极致