详解字典树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生成随机数的方法
Jan 14 Python
详解Django中Request对象的相关用法
Jul 17 Python
深入解析Python中的__builtins__内建对象
Jun 21 Python
Pandas 合并多个Dataframe(merge,concat)的方法
Jun 08 Python
uwsgi+nginx部署Django项目操作示例
Dec 04 Python
浅谈Pandas:Series和DataFrame间的算术元素
Dec 22 Python
pycharm打开命令行或Terminal的方法
Jan 16 Python
Python Selenium 之数据驱动测试的实现
Aug 01 Python
Python tkinter实现图片标注功能(完整代码)
Dec 08 Python
Django ORM filter() 的运用详解
May 14 Python
Python创建文件夹与文件的快捷方法
Dec 08 Python
Python实现为PDF去除水印的示例代码
Apr 03 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
桌面中心(三)修改数据库
2006/10/09 PHP
php cli 方式 在crotab中运行解决
2010/02/08 PHP
php echo 输出字符串函数详解
2010/05/13 PHP
使用php统计字符串中中英文字符的个数
2013/06/23 PHP
PHP实现的英文名字全拼随机排号脚本
2014/07/04 PHP
js+php实现静态页面实时调用用户登陆状态的方法
2015/01/04 PHP
Laravel6.2中用于用户登录的新密码确认流程详解
2019/10/16 PHP
javaScript 简单验证代码(用户名,密码,邮箱)
2009/09/28 Javascript
关于JavaScript定义类和对象的几种方式
2010/11/09 Javascript
原生js ActiveXObject获取execl里面的值
2013/11/01 Javascript
表单序列化与jq中的serialize使用示例
2014/02/21 Javascript
js离开或刷新页面检测(且兼容FF,IE,Chrome)
2014/03/05 Javascript
如何解决ligerUI布局时Center中的Tab高度大小
2015/11/24 Javascript
JavaScript操作select元素和option的实例代码
2016/01/29 Javascript
Node.js 条形码识别程序构建思路详解
2016/02/14 Javascript
jQuery实现伪分页的方法分享
2016/02/17 Javascript
JavaScript中的对象继承关系
2016/08/01 Javascript
jQuery下拉菜单的实现代码
2016/11/03 Javascript
jquery单击文字或图片内容放大并居中显示
2017/06/23 jQuery
vue+VeeValidate 校验范围实例详解(部分校验,全部校验)
2018/10/19 Javascript
Vue实现导航栏的显示开关控制
2019/11/01 Javascript
[06:43]2018DOTA2国际邀请赛寻真——VGJ.Thunder
2018/08/11 DOTA
python调用shell的方法
2013/11/20 Python
python实现的简单抽奖系统实例
2015/05/22 Python
windows环境下tensorflow安装过程详解
2018/03/30 Python
python使用Turtle库绘制动态钟表
2018/11/19 Python
Python3 venv搭建轻量级虚拟环境的步骤(图文)
2019/08/09 Python
基于python模拟bfs和dfs代码实例
2020/11/19 Python
SCDKey德国:全球领先的数字游戏市场
2019/04/09 全球购物
英国网上自行车商店:Tredz Bikes
2019/10/29 全球购物
2014年最新学习全国两会精神心得
2014/03/17 职场文书
2014企业领导班子四风对照检查材料思想汇报
2014/09/17 职场文书
教师批评与自我批评发言稿
2014/10/15 职场文书
先进工作者个人总结
2015/02/15 职场文书
2019升学宴主持词范本5篇
2019/10/09 职场文书
Java org.w3c.dom.Document 类方法引用报错
2021/08/07 Java/Android