前言


在实际应用场景中,很多时候我们会用到字典集的查找。通过一个键值key,去拿到它对应的值对象。这种方法确实很高效,很快,但是这里有个问题,当字典集储存的键值很多的情况时,毫无疑问,这里会消耗掉大量的内存空间。这个在我们做基数计数的统计应用时,这个空间会膨胀地特别厉害。本节笔者将要谈论的是对于基数统计来说,使用上更为适用的1种数据结构Trie Tree以及它的衍生优化版Radix Tree。

Trie Tree


我们先来看第一种树结构Trie Tree,名叫字典树。Trie Tree的原理是将每个key拆分成每个单位长度字符,然后对应到每个分支上,分支所在的节点对应为从根节点到当前节点的拼接出的key的值。它的结构图如下所示。

上图中每个节点存储的值为一个数值,当然这不是绝对的,我们可以假想这可以是key值所对应的任何值对象。只是计数统计在平时使用中更为常见一些。那么问题来了,相比较于字典集的存储方式,Trie Tree将key以树型结构构造,有什么用意呢?一个最大的帮助是公共的前缀被共享了,这样可以避免被重复地存储了。而在普通的字典集结构中,这种重复key前缀都是独立被包含在每个key内的。假设当字典集中所存储的key都带有大量重复的前缀时,Trie Tree将会消耗比普通字典结构更少的空间。

如上述所描述的,通过共享公共前缀的方式空间省了不少,但是它的查询效率如何呢?按照树的查询方式,一个查询key长度m,首先我们会将key拆分成m个字符,然后对应每个长度,从根节点依次向下,总共会进行到m次查找。因此我们可以得出,它的查询时间复杂度为O(m),随着查询key长度的增加,它所消耗的时间将会线性增长。

往深层面来看查询时间的问题,其实本质上这是树的深度引起的问题,对于长key而言,它的key对应的节点构造的深度过深。那么如果说我们将这“棵”树构造得更紧凑一些,会如何呢?于是我们有了另外一个衍生版本树:Radix Tree(基数树)。

Radix Tree


Radix Tree名为基数树,它的计数统计原理和Trie Tree极为相似,一个最大的区别点在于它不是按照每个字符长度做节点拆分,而是可以以1个或多个字符叠加作为一个分支。这就避免了长字符key会分出深度很深的节点。Radix Tree的结构构造如下图所示:


从上图我们可以看到,上面每个分支可以是局部部分字符串。以简单的字符查找为例,Radix Tree的搜索查找过程如下:

针对Radix Tree的构造规则,它的节点插入和删除行为相比较于Trie Tree来说,略有不同。

  • 对于节点插入而言,当有新的key进来,需要拆分原有公共前缀分支。
  • 对于节点删除而言,当删除一个现有key后,发现其父节点只有另外一个子节点key,则此子节点可以和父节点合并为一个新的节点,以此减少树的比较深度。

Radix Tree的insert过程如下图所示:

Trie Tree、Radix Tree的局限性


的确Trie Tree、Radix Tree在某些应用场景可以帮助我们节省内存使用空间,但是它们也有其使用的局限性。比如这类树结构无法适用于所有的数据类型,目前来看主要适用于能够用string字符等可作为表达式查询key的场景。

引用


[1].https://en.wikipedia.org/wiki/Radix_tree
[2].https://en.wikipedia.org/wiki/Trie

Trie Tree和Radix Tree相关推荐

  1. 原始Radix Tree与路径压缩

    原始Radix Tree与路径压缩 Radix Tree简介 Radix tree 是一种前缀字典树,它的主要特点是树的高度不随数据库大小和节点数量改变,而是由 key 的长度决定.B树需要根据数据量 ...

  2. WORT: Write Optimal Radix Tree for Persistent Memory Storage Systems

    WORT: Write Optimal Radix Tree for Persistent Memory Storage Systems FAST17的一篇文章,介绍了内存索引中使用基数树保证数据一致 ...

  3. Redis radix tree源码解析

    Redis实现了不定长压缩前缀的radix tree,用在集群模式下存储slot对应的的所有key信息.本文将详述在Redis中如何实现radix tree. 核心数据结构 raxNode是radix ...

  4. redis radix tree的简单解释

    所有例子均出自源码. Radix tree压缩前缀树,是redis在5.0新加入的用来存储key的数据结构. 前缀树的节点结构如下. typedef struct raxNode {uint32_t ...

  5. Linux: radix tree实现简析

    文章目录 1. 前言 2. 测试环境 3. 实现 3.1 概念 3.2 数据结构 3.3 对基数树的操作 3.3.1 初始化 3.3.2 插入 3.3.3 查找 3.3.4 删除 3.3.5 tag ...

  6. 【页高速缓存】radix tree 源码解析

    项目要在内核做和页高速缓存相类似缓存机制,在写内核代码之前必须先搞清楚页高速缓存源码是什么情况. 之前有一篇博客分析过了页高速缓存的基础,但是远远没有达到动手写代码的基础.这几天端午节假期集中精力,搞 ...

  7. 如何扩展Dojo tree成chekbox tree

    为什么80%的码农都做不了架构师?>>>    想找可以生产带有checkbox的树的js控件来做表单控件用,找了YUI, jquery plugin都觉的不怎么理想, 今天找一老外 ...

  8. 在windows上的git bash中安装tree 和 linux tree命令使用

    在windows上的git bash中安装tree 和 linux tree命令使用 文章目录: 1 在windows上的git bash中安装tree 1.1 下载windows版本的tree 1. ...

  9. BST、AVL、BTree、B+Tree、B*Tree、23Tree、234Tree、TTree、RBTree、LLRBTree、AATree、SplayTree、Treap、无旋Treap、scap

    喜欢这篇文章吗?喜欢的话去看博主的置顶博客,即可依据分类找到此文章的原版得到更好的体验, 图片及代码显示的问题,笔者深感抱歉,想要更好的体验去原博文即可. title: tree mathjax: t ...

  10. 【Leetcode】431. Encode N-ary Tree to Binary Tree(困难)

    一.题目 1.题目描述 Design an algorithm to encode an N-ary tree into a binary tree and decode the binary tre ...

最新文章

  1. python插件下载地址
  2. 2_Python实现基于人脸特征的美颜算法(20181224)
  3. Spring-boot 启动完成时执行指定任务
  4. boost::hana::repeat用法的测试程序
  5. 数据结构最短路径例题_数据结构算法实验8图的最短路径问题附源代码.doc
  6. 嵌套饼图_你真的了解matplotlib吗?---环形图
  7. 应用实时监控 ARMS 上线用户行为回溯功能
  8. 戴尔笔记本电脑开机黑屏怎么办_戴尔笔记本电脑充不进电怎么办
  9. STM32工作笔记0088---时间标志组和同时等待多个内核对象
  10. 网络协议从入门到底层原理(8)HTTPS(成本、通信过程、TLS1.2的连接,配置服务器HTTPS)
  11. 服务器音频文件缓存,音频文件如何缓存到本地,和播放缓存到本地的音频文件...
  12. @RequestBody、 @RequestParam 、 @PathVariable 和 @Vaild 注解的使用及区别
  13. bootstrapTable 数据格式
  14. X/Open和OSF
  15. 【SpringBoot】11、SpringBoot中使用Lombok
  16. 浏览器缓存机制及一些缓存问题解决方法
  17. 团体程序设计天梯赛 -- 练习集 (L1合集)
  18. Android怎么开启联想,联想Tab2A7-10F 开启USB调试模式
  19. 南京农业大学计算机博士几年毕业,通知 | 南京农业大学关于调整博士研究生基本学制及增加博士生培养环节要求的通知...
  20. 小程序开发经验分享(2)前端开发

热门文章

  1. ugui 转轮_Unity3D的FingerGesture插件
  2. Moon Modeler v1.6.5功能和特点
  3. 计算LTE 峰值速率
  4. html文本框换行,JS文本框的换行
  5. 最新2021计算机排名中国大学排名,2020-2021年计算机类专业排名_中国大学本科教育按专业类排行榜_中国科教评价网...
  6. 【SDOI2013】项链 题解
  7. 北京的程序猿们,今年过年去哪玩?
  8. 用人话说说文明和文化
  9. IDEA 中定义自己的TODO 并设置快捷键
  10. 《合约星期五》OKEx BTC季度合约 0726周报