6.6 van Emde Boas树
我将按四个步骤来逐一引入到van Emde Boas树。从位图到索引位图,再到van Emde Boas原型,最后到van Emde Boas树。
位图与索引位图
在java中有这个一个类,叫EnumSet。这个类只能存储枚举类型。枚举有个明显的特征,就是取值范围限定在有限个元素内,比如星期一到星期天可以用枚举来表示。EnumSet这个类的实现原理是位图,用每个位来表示元素是否存在,这样不仅节省了存储空间,也使得插入、删除操作性能非常高,时间复杂度为
O
(
1
)
O(1)
O(1)。
但是位图存在一个缺点,就是最小值minimum、最大值maximum、前任predecessor、后任successor这四种操作操作时间复杂度比较大。
为了提高这四种操作的性能,可以在位图上建立二叉树索引。二叉树每个节点取值只有两种,0或1。取值的依据是底层两个子节点的或运算结果,这样就可以知道子节点到底有没有某个元素。这样能更加快速地寻找最小值、最大值、前任、后任等。如下图所示,是找前任的搜索路径:
可以看到性能比较慢啊,虽然某些情况下比在位图上按顺序检索快一点,比如上图中找O的前任。但这不是我们想要的东西。
van Emde Boas原型
van Emde Boas原型proto van Emde Boas,是一种二进制结构。它是一种二进制结构,是在位图索引的基础上发展而来的。
先试想一下,降低层数,会是什么样的效果。
这种数据结构还不是是van Emde Boas原型结构。但是还不是我们最终需要的东西。但是很接近了。首先我们需要一个数组存储状态。这个新的数据结构节点有三个属性:元素最大数量,子节点统计和子节点数组。如下图所示是只存储偶数节点索引的van Emde Boas原型结构,u代表元素个数(图中是16个),s代表统计数据summary,c代表子节点数组cluster。
特别注意的是,当u=2时,由于不能继续细分,所以没有了summary和cluster属性。这已经非常接近van Emde Boas树了。
不同的在于,proto van Emde Boas只支持元素数量为2、4、16、256。也就是按
2
2
k
2^{2^k}
22k进行膨胀,比如:
2
2
0
=
2
1
=
2
2
2
1
=
2
2
=
4
2
2
2
=
2
4
=
16
2
2
3
=
2
8
=
256
2
2
4
=
2
16
=
65536
2
2
5
=
2
32
=
4294967296
2^{2^0} = 2^1=2\\ 2^{2^1} = 2^2= 4\\ 2^{2^2} = 2^{4}= 16\\ 2^{2^3} = 2^{8}= 256\\ 2^{2^4} = 2^{16}= 65536\\ 2^{2^5} = 2^{32}=4294967296
220=21=2221=22=4222=24=16223=28=256224=216=65536225=232=4294967296
所以van Emde Boas原型结构对元素数量的要求太严苛了。如果元素数量不是这个数,就容易造成内存空间的极大浪费。那怎么办?
van Emde Boas树
这个时候就需要对van Emde Boas继续改造,变成van Emde Boas树。van Emde Boas树的节点与van Emde Boas原型稍微有点不同。首先是节点多了两个属性min和max。min和max的处理还是有点不同。除min以外的才存储,也就是说min不会存储到任何cluster中。这样设计的目的是为了节省一点存储空间。但要注意,max还是要存的。
此外,对于最小的尺寸为2的叶子,也是有改变的,因为有min和max两个属性,所以就不需要底层数组了。
以u=16为例子,存储{2,3,4,5,7,14,15}这几个数据是这样的效果:
这种结构就节省了一些存储空间。这就是我们最终要的van Emde Boas树。
java代码实现
git 地址 https://e.coding.net/buildt/data-structure/trees.git
相关文章
- Red Hat Enterprise Linux 6.6安装体验
- Symantec Backup Exec Remote Agent 2010在Redhat Enterprise 6.6上启动问题
- RHEL 6.6安装桌面环境GNOME
- CentOS 6.5/6.6 安装(install)mysql 5.7 最完整版教程
- Linux CentOS 6.6安装JDK1.7
- CentOS 6.6 新安装系统的网络IP配置
- centos 6.6 Nginx 安装配置(已纠正)
- 阿里公共DNS正式发布:223.5.5.5 223.6.6.6
- 在线文档查看器:Gleamtech Document Viewer 6.6.1
- 你的NET程序需要保护吗?Agile.net 6.6.X 注入式Crack
- SQL DXP 6.6.x 高级版--最新版
- 6.6K Star,比 Pandas 快很多的数据处理库
- 6.6 van Emde Boas树
- 6.6 置换代数运算
- 习题 6.6 写一函数,求一个字符串的长度。在main函数中输入字符串,并输出其长度。
- 习题 6.6 输出以下的杨辉三角形(要求输出10行)
- 6.6 hadoop作业调优
- 6.6 jmeter基础—系统日志
- VC皮肤库SkinSharp 1.0.6.6的使用
- 6.6 random--伪随机数的生成
- 在Linux CentOS 6.6上安装Python 2.7.9
- logstash 6.6.0 读取nginx日志 插入到elasticsearch中
- 怎样安装CentOS 6.6之三:磁盘分区的划分和修改
- VaxVoIP SIP 服务器 SDK 6.8[6.6]