详解字典树Trie结构及其Python代码实现


Posted in Python onJune 03, 2016

字典树(Trie)可以保存一些字符串->值的对应关系。基本上,它跟 Java 的 HashMap 功能相同,都是 key-value 映射,只不过 Trie 的 key 只能是字符串。
Trie 的强大之处就在于它的时间复杂度。它的插入和查询时间复杂度都为 O(k) ,其中 k 为 key 的长度,与 Trie 中保存了多少个元素无关。Hash 表号称是 O(1) 的,但在计算 hash 的时候就肯定会是 O(k) ,而且还有碰撞之类的问题;Trie 的缺点是空间消耗很高。
至于Trie树的实现,可以用数组,也可以用指针动态分配,我做题时为了方便就用了数组,静态分配空间。
Trie树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。
Trie的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。
Trie树中每个单词都是通过character by character方法进行存储,相同前缀单词共享前缀节点.
可以看到,每条路径组成一个单词.上面这颗树存了to/tea/ted/ten/inn这些词.

Trie树的基本性质可以归纳为:
(1)根节点不包含字符,除根节点意外每个节点只包含一个字符。
(2)从根节点到某一个节点,路径上经过的字符连接起来,为该节点对应的字符串。
(3)每个节点的所有子节点包含的字符串不相同。

性质
(1)根节点不包含字符,除根节点外的每个节点只包含一个字符。
(2)从根节点到某一个节点,路径上经过的字符连接起来,为该节点对应的字符串。
(3)每个节点的所有子节点包含的字符串不相同。

基本思想(以字母树为例):
1、插入过程
对于一个单词,从根开始,沿着单词的各个字母所对应的树中的节点分支向下走,直到单词遍历完,将最后的节点标记为红色,表示该单词已插入Trie树。
2、查询过程
同样的,从根开始按照单词的字母顺序向下遍历trie树,一旦发现某个节点标记不存在或者单词遍历完成而最后的节点未标记为红色,则表示该单词不存在,若最后的节点标记为红色,表示该单词存在。

应用
(1)词频统计
比直接用hash节省空间
(2)搜索提示
输入前缀的时候提示可以构成的词
(3)作为辅助结构
如后缀树,AC自动机等的辅助结构

实现
虽然Python没有指针,但是可以用嵌套字典来实现树结构.对于非ascii的单词,统一用unicode编码来插入与搜索.

#coding=utf-8 
class Trie: 
  root = {} 
  END = '/' 
  def add(self, word): 
    #从根节点遍历单词,char by char,如果不存在则新增,最后加上一个单词结束标志 
    node = self.root 
    for c in word: 
      node=node.setdefault(c,{}) 
    node[self.END] = None 
 
  def find(self, word): 
    node = self.root 
    for c in word: 
      if c not in node: 
        return False 
      node = node[c] 
    return self.END in node
Python 相关文章推荐
python实现linux服务器批量修改密码并生成execl
Apr 22 Python
python判断字符串编码的简单实现方法(使用chardet)
Jul 01 Python
在win和Linux系统中python命令行运行的不同
Jul 03 Python
Python常用内置模块之xml模块(详解)
May 23 Python
python实现百万答题自动百度搜索答案
Jan 16 Python
python的re正则表达式实例代码
Jan 24 Python
python RabbitMQ 使用详细介绍(小结)
Nov 08 Python
python re库的正则表达式入门学习教程
Mar 08 Python
解决py2exe打包后,总是多显示一个DOS黑色窗口的问题
Jun 21 Python
Python3网络爬虫开发实战之极验滑动验证码的识别
Aug 02 Python
python gui开发——制作抖音无水印视频下载工具(附源码)
Feb 07 Python
Python还能这么玩之用Python修改了班花的开机密码
Jun 04 Python
Python中利用Scipy包的SIFT方法进行图片识别的实例教程
Jun 03 #Python
Python中的descriptor描述器简明使用指南
Jun 02 #Python
Python黑魔法Descriptor描述符的实例解析
Jun 02 #Python
深入理解Python变量与常量
Jun 02 #Python
Python中的Descriptor描述符学习教程
Jun 02 #Python
从源码解析Python的Flask框架中request对象的用法
Jun 02 #Python
Python搭建APNS苹果推送通知推送服务的相关模块使用指南
Jun 02 #Python
You might like
PHP 危险函数全解析
2009/09/09 PHP
smarty内置函数section的用法
2015/01/22 PHP
4种PHP异步执行的常用方式
2015/12/24 PHP
yii实现model添加默认值的方法(2种方法)
2016/01/06 PHP
php简单复制文件的方法
2016/05/09 PHP
PHP 读取大文件并显示的简单实例(推荐)
2016/08/12 PHP
javascript开发随笔二 动态加载js和文件
2011/11/25 Javascript
JavaScript调用ajax获取文本文件内容实现代码
2014/03/28 Javascript
javascript写的异步加载js文件函数(支持数组传参)
2014/06/07 Javascript
json+jQuery实现的无限级树形菜单效果代码
2015/08/27 Javascript
尝试动手制作javascript放大镜效果
2015/12/25 Javascript
详解JavaScript中localStorage使用要点
2016/01/13 Javascript
JavaScript中判断数据类型的方法总结
2016/05/24 Javascript
jQuery中slidedown与slideup方法用法示例
2016/09/16 Javascript
iView-admin 动态路由问题的解决方法
2018/10/03 Javascript
在 Vue 中使用 JSX 及使用它的原因浅析
2020/02/10 Javascript
vscode 调试 node.js的方法步骤
2020/09/15 Javascript
实现vuex原理的示例
2020/10/21 Javascript
python实现DES加密解密方法实例详解
2015/06/30 Python
详细解读Python中解析XML数据的方法
2015/10/15 Python
Python使用multiprocessing实现一个最简单的分布式作业调度系统
2016/03/14 Python
python用户管理系统
2018/03/13 Python
Python学习小技巧总结
2018/06/10 Python
Python 使用PIL中的resize进行缩放的实例讲解
2018/08/03 Python
详解Python中pandas的安装操作说明(傻瓜版)
2019/04/08 Python
Python正则表达式匹配日期与时间的方法
2019/07/07 Python
将python安装信息加入注册表的示例
2019/11/20 Python
spyder 在控制台(console)执行python文件,debug python程序方式
2020/04/20 Python
python+selenium自动化实战携带cookies模拟登陆微博
2021/01/19 Python
HTML5有哪些新特征
2015/12/01 HTML / CSS
经济与贸易专业应届生求职信
2013/11/19 职场文书
拓展策划方案
2014/06/03 职场文书
2014年内勤工作总结
2014/11/24 职场文书
2015年毕业生个人自荐书
2015/03/24 职场文书
物资采购管理制度
2015/08/06 职场文书
Java无向树分析 实现最小高度树
2022/04/09 Javascript