详解字典树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实现从脚本里运行scrapy的方法
Apr 07 Python
将Django框架和遗留的Web应用集成的方法
Jul 24 Python
Python中的getopt函数使用详解
Jul 28 Python
python简单读取大文件的方法
Jul 01 Python
python中将字典形式的数据循环插入Excel
Jan 16 Python
Python subprocess模块详细解读
Jan 29 Python
Python面向对象基础入门之编码细节与注意事项
Dec 11 Python
python 提取key 为中文的json 串方法
Dec 31 Python
深入理解Django-Signals信号量
Feb 19 Python
python实现两个字典合并,两个list合并
Dec 02 Python
python Shapely使用指南详解
Feb 18 Python
Python如何使用OS模块调用cmd
Feb 27 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数组去重的函数代码
2013/02/03 PHP
php中并发读写文件冲突的解决方案
2013/10/25 PHP
从父页面读取和操作iframe中内容方法
2009/07/25 Javascript
JavaScript 对话框和状态栏使用说明
2009/10/25 Javascript
找出字符串中出现次数最多的字母和出现次数精简版
2012/11/07 Javascript
按Enter键触发事件的jquery方法实现代码
2014/02/17 Javascript
jQuery学习笔记之jQuery原型属性和方法
2014/06/09 Javascript
JavaScript使用concat连接数组的方法
2015/04/06 Javascript
JS解析XML文件和XML字符串详解
2015/04/17 Javascript
javascript 常见功能汇总
2015/06/11 Javascript
Ionic实现仿通讯录点击滑动及$ionicscrolldelegate使用分析
2016/01/18 Javascript
jQuery Ajax 上传文件处理方式介绍(推荐)
2016/06/30 Javascript
AngularJS Ajax详解及示例代码
2016/08/17 Javascript
javascript实现二叉树遍历的代码
2017/06/08 Javascript
使用Vue的slot插槽分发父组件内容实现高度复用、更加灵活的组件(推荐)
2018/05/01 Javascript
vue之封装多个组件调用同一接口的案例
2020/08/11 Javascript
python基于ID3思想的决策树
2018/01/03 Python
记一次python 内存泄漏问题及解决过程
2018/11/29 Python
Python批量生成特定尺寸图片及图画任意文字的实例
2019/01/30 Python
Python3.4学习笔记之列表、数组操作示例
2019/03/01 Python
python学习开发mock接口
2019/04/28 Python
如何将 awk 脚本移植到 Python
2019/12/09 Python
Python文件操作函数用法实例详解
2019/12/24 Python
Python pyautogui模块实现鼠标键盘自动化方法详解
2020/02/17 Python
Python序列化pickle模块使用详解
2020/03/05 Python
python thrift 实现 单端口多服务的过程
2020/06/08 Python
Python装饰器结合递归原理解析
2020/07/02 Python
HTML5 Canvas中绘制矩形实例
2015/01/01 HTML / CSS
ProBikeKit新西兰:自行车套件,跑步和铁人三项装备
2017/04/05 全球购物
第一范式(1NF)、第二范式(2NF)和第三范式(3NF)之间的区别是什么?
2016/04/28 面试题
党的群众路线教育实践活动实施方案
2014/10/31 职场文书
2014年平安创建工作总结
2014/11/24 职场文书
电影雷锋观后感
2015/06/10 职场文书
2016教师读书思廉心得体会
2016/01/23 职场文书
学校运动会开幕词
2016/03/03 职场文书
golang生成vcf通讯录格式文件详情
2022/03/25 Golang