前言:本文章来源于我在知乎上回答的一个问题
AVL树,红黑树,B树,B+树,Trie树都分别应用在哪些现实场景中?
看完后您可能会了解到这些数据结构大致的原理及为什么用在这些场景,文章并不涉及具体操作(如插入删除等等)
目录
- AVL树
- AVL树原理与应用
- 红黑树
- 红黑树原理与应用
- B/B+树
- B/B+树原理与应用
- Trie树
- Trie树原理与应用
AVL树
简介:
AVL树是最早的自平衡二叉树,在早期应用还相对来说比较广,后期由于旋转次数过多而被红黑树等结构取代(二者都是用来搜索的),AVL树内部是有序的。
原理:
平衡二叉树,一般是用平衡因子差值判断是否平衡并通过旋转来实现平衡,左右子树树高差不超过1,那么和红黑树比较它是严格的平衡二叉树,平衡条件非常严格(树高差只有1),只要插入或删除不满足上面的条件就要通过旋转来保持平衡。由于旋转是非常耗费时间的。我们可以推出AVL树适合用于插入删除次数比较少,但查找多的情况,并且保证深度是Olog(n)。
下图为一棵AVL树
侧边是平衡因子,我们可以看到任意节点的左右子树的平衡因子差值都不会大于1,所以维持这颗强平衡二叉树的条件就非常严格了。
应用:
Windows内核通过AVL树来保存一些离散的地址空间.
原因可能是访问次数多于插入删除的次数。AVL树的高度较低于红黑树等
红黑树
简介:
平衡二叉树,由于旋转次数较少在插入删除操作多的情况下性能高于其他平衡二叉树,所以被广泛应用。内部是有序的
原理:
平衡二叉树,通过对任何一条从根到叶子的简单路径上各个节点的颜色进行约束(红和黑),确保没有一条路径会比其他路径长2倍,因而是近似平衡的(一个节点的两棵子树高度不会相差二倍),是一棵弱平衡二叉树。所以相对于严格要求平衡的AVL树来说,它的旋转保持平衡次数较少。用于搜索时,插入删除次数多的情况下我们就用红黑树来取代AVL。
一个简单的红黑树
应用:
1.c++STL 包括set,multiset,map,multimap(侯捷前辈的STL源码剖析比较详细)。c++关联容器
java容器中的TreeMap2.IO多路复用的epoll,内部用红黑树来维持我们想要监控的socket。以支持快速的插入和删除
3.nginx中定时器是用红黑树来维持的,因为红黑树是有序的,每次从红黑树内部取出最小的定时器即可。
4.linux内核中用红黑树来管理进程的内存使用,进程的虚拟地址空间块都以虚拟地址为key值挂在这棵红黑树上。
B/B+树
B-树参考这篇文章:) 从 MongoDB 及 Mysql 谈B/B+树
简介:
B/B+树主要用在数据库或者大型索引数据中,是一种多路查找树。(注意B树和B-树是同一个,B-树不是”B减树”,”-“仅仅是个符号)
原理:
B树,B+树:它们特点是一样的,是多路查找树,一般用于数据库系统中,为什么,因为它们分支多层数少呗(一般一个节点有成千上万个子节点,所以B树层数是非常少的,节点个数为N个高度为logN,但是这个log的底数不是我们常用的2了,而是一个节点的子节点个个数,底数非常大从而树高度很低),都知道磁盘IO是非常耗时的(和内存访问速度差千倍),而像大量数据存储在磁盘中所以我们要有效的减少磁盘IO次数避免磁盘频繁的查找。减少磁盘IO就意味着提升性能。B+树是B树的变种树,有n棵子树的节点中含有n个关键字,每个关键字不保存数据(也就是节点只保存key),只用来索引,数据都保存在叶子节点。是为文件系统而生的。
一棵B树
一棵B+树
应用:
B树一般用在数据库等大型索引,主要原因就是层数少,重点—>减少避免磁盘IO
B+树适应文件系统,想下文件系统的样子,目录并不保存文件只有底层叶子节点保存数据。
Trie树
简介:
又名单词查找树,主要处理字符串,字符串的相同前缀保存在相同的节点中。它的变种树非常多。
比如:
前缀树(prefix tree),后缀树(suffix tree)
详情见 从前缀树谈到后缀树radix tree(patricia tree, compact prefix tree, 基数树)
crit-bit tree(解决耗费内存问题)
原理:
它是不同字符串的相同前缀只保存一份。
相对直接保存字符串肯定是节省空间的,但是它保存大量字符串时会很耗费内存(是内存)。
类似下图
应用:
前缀树(prefix tree):
1.字符串快速检索
2.字符串排序
3.最长公共前缀
4.自动匹配前缀显示后缀。后缀树(suffix tree):
1.查找字符串s1在s2中
2.字符串s1在s2中出现的次数
3.字符串s1,s2最长公共部分
4.最长回文串
详情还是见
从前缀树谈到后缀树radix树:
1.ip路由表–《TCP/IP详解卷2:实现》笔记–Radix树路由表
2.linux内核内存管理–戳linux内核radix
完