详解字典树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统计文件行数示例分享
Feb 21 Python
python随机取list中的元素方法
Apr 08 Python
基于Python实现定时自动给微信好友发送天气预报
Oct 25 Python
django 控制页面跳转的例子
Aug 06 Python
python基础教程之while循环
Aug 14 Python
python3 requests库实现多图片爬取教程
Dec 18 Python
Python configparser模块配置文件过程解析
Mar 03 Python
Python学习之路安装pycharm的教程详解
Jun 17 Python
详解修改Anaconda中的Jupyter Notebook默认工作路径的三种方式
Jan 24 Python
Python调用SMTP服务自动发送Email的实现步骤
Feb 07 Python
解决numpy和torch数据类型转化的问题
May 23 Python
Python用any()函数检查字符串中的字母以及如何使用all()函数
Apr 14 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脚本的10个技巧(1)
2006/10/09 PHP
php简单封装了一些常用JS操作
2007/02/25 PHP
php删除字符串末尾子字符,删除开始字符,删除两端字符(实现代码)
2013/06/27 PHP
laravel学习教程之存取器
2016/07/30 PHP
Thinkphp框架 表单自动验证登录注册 ajax自动验证登录注册
2016/12/27 PHP
js资料prototype 属性
2007/03/13 Javascript
精通Javascript系列之数据类型 字符串
2011/06/08 Javascript
jquery应该如何来设置改变按钮input的onclick事件
2012/12/10 Javascript
Windows 系统下安装和部署Egret的开发环境
2014/07/31 Javascript
AngularJS自动表单验证
2016/02/01 Javascript
Web打印解决方案之普通报表打印功能
2016/08/29 Javascript
AngularJS ng-repeat数组有重复值的解决方法
2016/10/23 Javascript
javascript中Number的方法小结
2016/11/21 Javascript
jquery实现下拉框多选方法介绍
2017/01/03 Javascript
微信小程序之网络请求简单封装实例详解
2017/06/28 Javascript
解决Webpack 热部署检测不到文件变化的问题
2018/02/22 Javascript
jQuery实现为table表格动态添加或删除tr功能示例
2019/02/19 jQuery
详解Js里的for…in和for…of的用法
2019/03/28 Javascript
使用imba.io框架得到比 vue 快50倍的性能基准
2019/06/17 Javascript
如何使用three.js 制作一个三维的推箱子游戏
2020/07/29 Javascript
Python统计列表中的重复项出现的次数的方法
2014/08/18 Python
十分钟利用Python制作属于你自己的个性logo
2018/05/07 Python
Python实现监控键盘鼠标操作示例【基于pyHook与pythoncom模块】
2018/09/04 Python
使用11行Python代码盗取了室友的U盘内容
2018/10/23 Python
python实现统计代码行数的小工具
2019/09/19 Python
通过python3实现投票功能代码实例
2019/09/26 Python
日本著名化妆品零售网站:Cosme Land
2019/03/01 全球购物
美国小蜜蜂Burt’s Bees德国官网:天然唇部、皮肤和身体护理产品
2020/06/14 全球购物
关于读书的活动方案
2014/08/14 职场文书
校园环保广播稿(3篇)
2014/09/15 职场文书
骨干教师个人总结
2015/02/11 职场文书
高中升旗仪式主持词
2015/07/03 职场文书
学校运动会通讯稿
2015/07/18 职场文书
应收账款管理制度
2015/08/06 职场文书
创业计划书之宠物店
2019/09/19 职场文书
彩虹社八名人气艺人全新周边限时推出,性转女装男装一次拥有!
2022/04/01 日漫